1// Copyright (C) 2023 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QRHIGLES2_P_H
5#define QRHIGLES2_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include "qrhi_p.h"
19#include <rhi/qshaderdescription.h>
20#include <qopengl.h>
21#include <QByteArray>
22#include <QWindow>
23#include <QPointer>
24#include <QtCore/private/qduplicatetracker_p.h>
25#include <optional>
26
27QT_BEGIN_NAMESPACE
28
29class QOpenGLExtensions;
30class QRhiGles2;
31
32struct QGles2Buffer : public QRhiBuffer
33{
34 QGles2Buffer(QRhiImplementation *rhi, Type type, UsageFlags usage, quint32 size);
35 ~QGles2Buffer();
36 void destroy() override;
37 bool create() override;
38 QRhiBuffer::NativeBuffer nativeBuffer() override;
39 char *beginFullDynamicBufferUpdateForCurrentFrame() override;
40 void endFullDynamicBufferUpdateForCurrentFrame() override;
41 void fullDynamicBufferUpdateForCurrentFrame(const void *data, quint32 size) override;
42
43 quint32 nonZeroSize = 0;
44 GLuint buffer = 0;
45 GLenum targetForDataOps;
46 QByteArray data;
47 enum Access {
48 AccessNone,
49 AccessVertex,
50 AccessIndex,
51 AccessUniform,
52 AccessStorageRead,
53 AccessStorageWrite,
54 AccessStorageReadWrite,
55 AccessUpdate
56 };
57 struct UsageState {
58 Access access;
59 };
60 UsageState usageState;
61 friend class QRhiGles2;
62};
63
64struct QGles2RenderBuffer : public QRhiRenderBuffer
65{
66 QGles2RenderBuffer(QRhiImplementation *rhi, Type type, const QSize &pixelSize,
67 int sampleCount, QRhiRenderBuffer::Flags flags,
68 QRhiTexture::Format backingFormatHint);
69 ~QGles2RenderBuffer();
70 void destroy() override;
71 bool create() override;
72 bool createFrom(NativeRenderBuffer src) override;
73 QRhiTexture::Format backingFormat() const override;
74
75 GLuint renderbuffer = 0;
76 GLuint stencilRenderbuffer = 0; // when packed depth-stencil not supported
77 int samples;
78 bool owns = true;
79 uint generation = 0;
80 friend class QRhiGles2;
81};
82
83struct QGles2SamplerData
84{
85 GLenum glminfilter = 0;
86 GLenum glmagfilter = 0;
87 GLenum glwraps = 0;
88 GLenum glwrapt = 0;
89 GLenum glwrapr = 0;
90 GLenum gltexcomparefunc = 0;
91};
92
93inline bool operator==(const QGles2SamplerData &a, const QGles2SamplerData &b)
94{
95 return a.glminfilter == b.glminfilter
96 && a.glmagfilter == b.glmagfilter
97 && a.glwraps == b.glwraps
98 && a.glwrapt == b.glwrapt
99 && a.glwrapr == b.glwrapr
100 && a.gltexcomparefunc == b.gltexcomparefunc;
101}
102
103inline bool operator!=(const QGles2SamplerData &a, const QGles2SamplerData &b)
104{
105 return !(a == b);
106}
107
108struct QGles2Texture : public QRhiTexture
109{
110 QGles2Texture(QRhiImplementation *rhi, Format format, const QSize &pixelSize, int depth,
111 int arraySize, int sampleCount, Flags flags);
112 ~QGles2Texture();
113 void destroy() override;
114 bool create() override;
115 bool createFrom(NativeTexture src) override;
116 NativeTexture nativeTexture() override;
117
118 bool prepareCreate(QSize *adjustedSize = nullptr);
119
120 GLuint texture = 0;
121 bool owns = true;
122 GLenum target;
123 GLenum glintformat;
124 GLenum glsizedintformat;
125 GLenum glformat;
126 GLenum gltype;
127 QGles2SamplerData samplerState;
128 bool specified = false;
129 bool zeroInitialized = false;
130 int mipLevelCount = 0;
131
132 enum Access {
133 AccessNone,
134 AccessSample,
135 AccessFramebuffer,
136 AccessStorageRead,
137 AccessStorageWrite,
138 AccessStorageReadWrite,
139 AccessUpdate,
140 AccessRead
141 };
142 struct UsageState {
143 Access access;
144 };
145 UsageState usageState;
146
147 uint generation = 0;
148 friend class QRhiGles2;
149};
150
151struct QGles2Sampler : public QRhiSampler
152{
153 QGles2Sampler(QRhiImplementation *rhi, Filter magFilter, Filter minFilter, Filter mipmapMode,
154 AddressMode u, AddressMode v, AddressMode w);
155 ~QGles2Sampler();
156 void destroy() override;
157 bool create() override;
158
159 QGles2SamplerData d;
160 uint generation = 0;
161 friend class QRhiGles2;
162};
163
164struct QGles2RenderPassDescriptor : public QRhiRenderPassDescriptor
165{
166 QGles2RenderPassDescriptor(QRhiImplementation *rhi);
167 ~QGles2RenderPassDescriptor();
168 void destroy() override;
169 bool isCompatible(const QRhiRenderPassDescriptor *other) const override;
170 QRhiRenderPassDescriptor *newCompatibleRenderPassDescriptor() const override;
171 QVector<quint32> serializedFormat() const override;
172};
173
174struct QGles2RenderTargetData
175{
176 QGles2RenderTargetData(QRhiImplementation *) { }
177
178 bool isValid() const { return rp != nullptr; }
179
180 QGles2RenderPassDescriptor *rp = nullptr;
181 QSize pixelSize;
182 float dpr = 1;
183 int sampleCount = 1;
184 int colorAttCount = 0;
185 int dsAttCount = 0;
186 bool srgbUpdateAndBlend = false;
187 QRhiRenderTargetAttachmentTracker::ResIdList currentResIdList;
188 std::optional<QRhiSwapChain::StereoTargetBuffer> stereoTarget;
189};
190
191struct QGles2SwapChainRenderTarget : public QRhiSwapChainRenderTarget
192{
193 QGles2SwapChainRenderTarget(QRhiImplementation *rhi, QRhiSwapChain *swapchain);
194 ~QGles2SwapChainRenderTarget();
195 void destroy() override;
196
197 QSize pixelSize() const override;
198 float devicePixelRatio() const override;
199 int sampleCount() const override;
200
201 QGles2RenderTargetData d;
202};
203
204struct QGles2TextureRenderTarget : public QRhiTextureRenderTarget
205{
206 QGles2TextureRenderTarget(QRhiImplementation *rhi, const QRhiTextureRenderTargetDescription &desc, Flags flags);
207 ~QGles2TextureRenderTarget();
208 void destroy() override;
209
210 QSize pixelSize() const override;
211 float devicePixelRatio() const override;
212 int sampleCount() const override;
213
214 QRhiRenderPassDescriptor *newCompatibleRenderPassDescriptor() override;
215 bool create() override;
216
217 QGles2RenderTargetData d;
218 GLuint framebuffer = 0;
219 GLuint nonMsaaThrowawayDepthTexture = 0;
220 friend class QRhiGles2;
221};
222
223struct QGles2ShaderResourceBindings : public QRhiShaderResourceBindings
224{
225 QGles2ShaderResourceBindings(QRhiImplementation *rhi);
226 ~QGles2ShaderResourceBindings();
227 void destroy() override;
228 bool create() override;
229 void updateResources(UpdateFlags flags) override;
230
231 bool hasDynamicOffset = false;
232 uint generation = 0;
233 friend class QRhiGles2;
234};
235
236struct QGles2UniformDescription
237{
238 QShaderDescription::VariableType type;
239 int glslLocation;
240 int binding;
241 quint32 offset;
242 quint32 size;
243 int arrayDim;
244};
245
246Q_DECLARE_TYPEINFO(QGles2UniformDescription, Q_RELOCATABLE_TYPE);
247
248struct QGles2SamplerDescription
249{
250 int glslLocation;
251 int combinedBinding;
252 int tbinding;
253 int sbinding;
254};
255
256Q_DECLARE_TYPEINFO(QGles2SamplerDescription, Q_RELOCATABLE_TYPE);
257
258using QGles2UniformDescriptionVector = QVarLengthArray<QGles2UniformDescription, 8>;
259using QGles2SamplerDescriptionVector = QVarLengthArray<QGles2SamplerDescription, 4>;
260
261struct QGles2UniformState
262{
263 static constexpr int MAX_TRACKED_LOCATION = 1023;
264 int componentCount;
265 float v[4];
266};
267
268struct QGles2GraphicsPipeline : public QRhiGraphicsPipeline
269{
270 QGles2GraphicsPipeline(QRhiImplementation *rhi);
271 ~QGles2GraphicsPipeline();
272 void destroy() override;
273 bool create() override;
274
275 GLuint program = 0;
276 GLenum drawMode = GL_TRIANGLES;
277 QGles2UniformDescriptionVector uniforms;
278 QGles2SamplerDescriptionVector samplers;
279 QGles2UniformState uniformState[QGles2UniformState::MAX_TRACKED_LOCATION + 1];
280 QRhiShaderResourceBindings *currentSrb = nullptr;
281 uint currentSrbGeneration = 0;
282 uint generation = 0;
283 friend class QRhiGles2;
284};
285
286struct QGles2ComputePipeline : public QRhiComputePipeline
287{
288 QGles2ComputePipeline(QRhiImplementation *rhi);
289 ~QGles2ComputePipeline();
290 void destroy() override;
291 bool create() override;
292
293 GLuint program = 0;
294 QGles2UniformDescriptionVector uniforms;
295 QGles2SamplerDescriptionVector samplers;
296 QGles2UniformState uniformState[QGles2UniformState::MAX_TRACKED_LOCATION + 1];
297 QRhiShaderResourceBindings *currentSrb = nullptr;
298 uint currentSrbGeneration = 0;
299 uint generation = 0;
300 friend class QRhiGles2;
301};
302
303struct QGles2CommandBuffer : public QRhiCommandBuffer
304{
305 QGles2CommandBuffer(QRhiImplementation *rhi);
306 ~QGles2CommandBuffer();
307 void destroy() override;
308
309 // keep at a reasonably low value otherwise sizeof Command explodes
310 static const int MAX_DYNAMIC_OFFSET_COUNT = 8;
311
312 struct Command {
313 enum Cmd {
314 BeginFrame,
315 EndFrame,
316 ResetFrame,
317 Viewport,
318 Scissor,
319 BlendConstants,
320 StencilRef,
321 BindVertexBuffer,
322 BindIndexBuffer,
323 Draw,
324 DrawIndexed,
325 BindGraphicsPipeline,
326 BindShaderResources,
327 BindFramebuffer,
328 Clear,
329 BufferSubData,
330 GetBufferSubData,
331 CopyTex,
332 ReadPixels,
333 SubImage,
334 CompressedImage,
335 CompressedSubImage,
336 BlitFromRenderbuffer,
337 BlitFromTexture,
338 GenMip,
339 BindComputePipeline,
340 Dispatch,
341 BarriersForPass,
342 Barrier,
343 InvalidateFramebuffer
344 };
345 Cmd cmd;
346
347 // QRhi*/QGles2* references should be kept at minimum (so no
348 // QRhiTexture/Buffer/etc. pointers).
349 union Args {
350 struct {
351 GLuint timestampQuery;
352 } beginFrame;
353 struct {
354 GLuint timestampQuery;
355 } endFrame;
356 struct {
357 float x, y, w, h;
358 float d0, d1;
359 } viewport;
360 struct {
361 int x, y, w, h;
362 } scissor;
363 struct {
364 float r, g, b, a;
365 } blendConstants;
366 struct {
367 quint32 ref;
368 QRhiGraphicsPipeline *ps;
369 } stencilRef;
370 struct {
371 QRhiGraphicsPipeline *ps;
372 GLuint buffer;
373 quint32 offset;
374 int binding;
375 } bindVertexBuffer;
376 struct {
377 GLuint buffer;
378 quint32 offset;
379 GLenum type;
380 } bindIndexBuffer;
381 struct {
382 QRhiGraphicsPipeline *ps;
383 quint32 vertexCount;
384 quint32 firstVertex;
385 quint32 instanceCount;
386 quint32 baseInstance;
387 } draw;
388 struct {
389 QRhiGraphicsPipeline *ps;
390 quint32 indexCount;
391 quint32 firstIndex;
392 quint32 instanceCount;
393 quint32 baseInstance;
394 qint32 baseVertex;
395 } drawIndexed;
396 struct {
397 QRhiGraphicsPipeline *ps;
398 } bindGraphicsPipeline;
399 struct {
400 QRhiGraphicsPipeline *maybeGraphicsPs;
401 QRhiComputePipeline *maybeComputePs;
402 QRhiShaderResourceBindings *srb;
403 int dynamicOffsetCount;
404 uint dynamicOffsetPairs[MAX_DYNAMIC_OFFSET_COUNT * 2]; // binding, offset
405 } bindShaderResources;
406 struct {
407 GLbitfield mask;
408 float c[4];
409 float d;
410 quint32 s;
411 } clear;
412 struct {
413 GLuint fbo;
414 bool srgb;
415 int colorAttCount;
416 bool stereo;
417 QRhiSwapChain::StereoTargetBuffer stereoTarget;
418 } bindFramebuffer;
419 struct {
420 GLenum target;
421 GLuint buffer;
422 int offset;
423 int size;
424 const void *data; // must come from retainData()
425 } bufferSubData;
426 struct {
427 QRhiReadbackResult *result;
428 GLenum target;
429 GLuint buffer;
430 int offset;
431 int size;
432 } getBufferSubData;
433 struct {
434 GLenum srcTarget;
435 GLenum srcFaceTarget;
436 GLuint srcTexture;
437 int srcLevel;
438 int srcX;
439 int srcY;
440 int srcZ;
441 GLenum dstTarget;
442 GLuint dstTexture;
443 GLenum dstFaceTarget;
444 int dstLevel;
445 int dstX;
446 int dstY;
447 int dstZ;
448 int w;
449 int h;
450 } copyTex;
451 struct {
452 QRhiReadbackResult *result;
453 GLuint texture;
454 int w;
455 int h;
456 QRhiTexture::Format format;
457 GLenum readTarget;
458 int level;
459 int slice3D;
460 } readPixels;
461 struct {
462 GLenum target;
463 GLuint texture;
464 GLenum faceTarget;
465 int level;
466 int dx;
467 int dy;
468 int dz;
469 int w;
470 int h;
471 GLenum glformat;
472 GLenum gltype;
473 int rowStartAlign;
474 int rowLength;
475 const void *data; // must come from retainImage()
476 } subImage;
477 struct {
478 GLenum target;
479 GLuint texture;
480 GLenum faceTarget;
481 int level;
482 GLenum glintformat;
483 int w;
484 int h;
485 int depth;
486 int size;
487 const void *data; // must come from retainData()
488 } compressedImage;
489 struct {
490 GLenum target;
491 GLuint texture;
492 GLenum faceTarget;
493 int level;
494 int dx;
495 int dy;
496 int dz;
497 int w;
498 int h;
499 GLenum glintformat;
500 int size;
501 const void *data; // must come from retainData()
502 } compressedSubImage;
503 struct {
504 GLuint renderbuffer;
505 int w;
506 int h;
507 GLenum target;
508 GLuint dstTexture;
509 int dstLevel;
510 int dstLayer;
511 bool isDepthStencil;
512 } blitFromRenderbuffer;
513 struct {
514 GLenum srcTarget;
515 GLuint srcTexture;
516 int srcLevel;
517 int srcLayer;
518 int w;
519 int h;
520 GLenum dstTarget;
521 GLuint dstTexture;
522 int dstLevel;
523 int dstLayer;
524 bool isDepthStencil;
525 } blitFromTexture;
526 struct {
527 GLenum target;
528 GLuint texture;
529 } genMip;
530 struct {
531 QRhiComputePipeline *ps;
532 } bindComputePipeline;
533 struct {
534 GLuint x;
535 GLuint y;
536 GLuint z;
537 } dispatch;
538 struct {
539 int trackerIndex;
540 } barriersForPass;
541 struct {
542 GLbitfield barriers;
543 } barrier;
544 struct {
545 int attCount;
546 GLenum att[3];
547 } invalidateFramebuffer;
548 } args;
549 };
550
551 enum PassType {
552 NoPass,
553 RenderPass,
554 ComputePass
555 };
556
557 QRhiBackendCommandList<Command> commands;
558 QVarLengthArray<QRhiPassResourceTracker, 8> passResTrackers;
559 int currentPassResTrackerIndex;
560
561 PassType recordingPass;
562 bool passNeedsResourceTracking;
563 double lastGpuTime = 0;
564 QRhiRenderTarget *currentTarget;
565 QRhiGraphicsPipeline *currentGraphicsPipeline;
566 QRhiComputePipeline *currentComputePipeline;
567 uint currentPipelineGeneration;
568 QRhiShaderResourceBindings *currentGraphicsSrb;
569 QRhiShaderResourceBindings *currentComputeSrb;
570 uint currentSrbGeneration;
571
572 struct GraphicsPassState {
573 bool valid = false;
574 bool scissor;
575 bool cullFace;
576 GLenum cullMode;
577 GLenum frontFace;
578 bool blendEnabled;
579 struct ColorMask { bool r, g, b, a; } colorMask;
580 struct Blend {
581 GLenum srcColor;
582 GLenum dstColor;
583 GLenum srcAlpha;
584 GLenum dstAlpha;
585 GLenum opColor;
586 GLenum opAlpha;
587 } blend;
588 bool depthTest;
589 bool depthWrite;
590 GLenum depthFunc;
591 bool stencilTest;
592 GLuint stencilReadMask;
593 GLuint stencilWriteMask;
594 struct StencilFace {
595 GLenum func;
596 GLenum failOp;
597 GLenum zfailOp;
598 GLenum zpassOp;
599 } stencil[2]; // front, back
600 bool polyOffsetFill;
601 float polyOffsetFactor;
602 float polyOffsetUnits;
603 float lineWidth;
604 int cpCount;
605 GLenum polygonMode;
606 void reset() { valid = false; }
607 struct {
608 // not part of QRhiGraphicsPipeline but used by setGraphicsPipeline()
609 GLint stencilRef = 0;
610 } dynamic;
611 } graphicsPassState;
612
613 struct ComputePassState {
614 enum Access {
615 Read = 0x01,
616 Write = 0x02
617 };
618 QHash<QRhiResource *, QPair<int, bool> > writtenResources;
619 void reset() {
620 writtenResources.clear();
621 }
622 } computePassState;
623
624 struct TextureUnitState {
625 void *ps;
626 uint psGeneration;
627 uint texture;
628 } textureUnitState[16];
629
630 QVarLengthArray<QByteArray, 4> dataRetainPool;
631 QVarLengthArray<QRhiBufferData, 4> bufferDataRetainPool;
632 QVarLengthArray<QImage, 4> imageRetainPool;
633
634 // relies heavily on implicit sharing (no copies of the actual data will be made)
635 const void *retainData(const QByteArray &data) {
636 dataRetainPool.append(t: data);
637 return dataRetainPool.last().constData();
638 }
639 const uchar *retainBufferData(const QRhiBufferData &data) {
640 bufferDataRetainPool.append(t: data);
641 return reinterpret_cast<const uchar *>(bufferDataRetainPool.last().constData());
642 }
643 const void *retainImage(const QImage &image) {
644 imageRetainPool.append(t: image);
645 return imageRetainPool.last().constBits();
646 }
647 void resetCommands() {
648 commands.reset();
649 dataRetainPool.clear();
650 bufferDataRetainPool.clear();
651 imageRetainPool.clear();
652
653 passResTrackers.clear();
654 currentPassResTrackerIndex = -1;
655 }
656 void resetState() {
657 recordingPass = NoPass;
658 passNeedsResourceTracking = true;
659 // do not zero lastGpuTime
660 currentTarget = nullptr;
661 resetCommands();
662 resetCachedState();
663 }
664 void resetCachedState() {
665 currentGraphicsPipeline = nullptr;
666 currentComputePipeline = nullptr;
667 currentPipelineGeneration = 0;
668 currentGraphicsSrb = nullptr;
669 currentComputeSrb = nullptr;
670 currentSrbGeneration = 0;
671 graphicsPassState.reset();
672 computePassState.reset();
673 memset(s: textureUnitState, c: 0, n: sizeof(textureUnitState));
674 }
675};
676
677inline bool operator==(const QGles2CommandBuffer::GraphicsPassState::StencilFace &a,
678 const QGles2CommandBuffer::GraphicsPassState::StencilFace &b)
679{
680 return a.func == b.func
681 && a.failOp == b.failOp
682 && a.zfailOp == b.zfailOp
683 && a.zpassOp == b.zpassOp;
684}
685
686inline bool operator!=(const QGles2CommandBuffer::GraphicsPassState::StencilFace &a,
687 const QGles2CommandBuffer::GraphicsPassState::StencilFace &b)
688{
689 return !(a == b);
690}
691
692inline bool operator==(const QGles2CommandBuffer::GraphicsPassState::ColorMask &a,
693 const QGles2CommandBuffer::GraphicsPassState::ColorMask &b)
694{
695 return a.r == b.r && a.g == b.g && a.b == b.b && a.a == b.a;
696}
697
698inline bool operator!=(const QGles2CommandBuffer::GraphicsPassState::ColorMask &a,
699 const QGles2CommandBuffer::GraphicsPassState::ColorMask &b)
700{
701 return !(a == b);
702}
703
704inline bool operator==(const QGles2CommandBuffer::GraphicsPassState::Blend &a,
705 const QGles2CommandBuffer::GraphicsPassState::Blend &b)
706{
707 return a.srcColor == b.srcColor
708 && a.dstColor == b.dstColor
709 && a.srcAlpha == b.srcAlpha
710 && a.dstAlpha == b.dstAlpha
711 && a.opColor == b.opColor
712 && a.opAlpha == b.opAlpha;
713}
714
715inline bool operator!=(const QGles2CommandBuffer::GraphicsPassState::Blend &a,
716 const QGles2CommandBuffer::GraphicsPassState::Blend &b)
717{
718 return !(a == b);
719}
720
721struct QGles2SwapChainTimestamps
722{
723 static const int TIMESTAMP_PAIRS = 2;
724
725 bool active[TIMESTAMP_PAIRS] = {};
726 GLuint query[TIMESTAMP_PAIRS * 2] = {};
727
728 void prepare(QRhiGles2 *rhiD);
729 void destroy(QRhiGles2 *rhiD);
730 bool tryQueryTimestamps(int pairIndex, QRhiGles2 *rhiD, double *elapsedSec);
731};
732
733struct QGles2SwapChain : public QRhiSwapChain
734{
735 QGles2SwapChain(QRhiImplementation *rhi);
736 ~QGles2SwapChain();
737 void destroy() override;
738
739 QRhiCommandBuffer *currentFrameCommandBuffer() override;
740 QRhiRenderTarget *currentFrameRenderTarget() override;
741 QRhiRenderTarget *currentFrameRenderTarget(StereoTargetBuffer targetBuffer) override;
742
743 QSize surfacePixelSize() override;
744 bool isFormatSupported(Format f) override;
745
746 QRhiRenderPassDescriptor *newCompatibleRenderPassDescriptor() override;
747 bool createOrResize() override;
748
749 void initSwapChainRenderTarget(QGles2SwapChainRenderTarget *rt);
750
751 QSurface *surface = nullptr;
752 QSize pixelSize;
753 QGles2SwapChainRenderTarget rt;
754 QGles2SwapChainRenderTarget rtLeft;
755 QGles2SwapChainRenderTarget rtRight;
756 QGles2CommandBuffer cb;
757 int frameCount = 0;
758 QGles2SwapChainTimestamps timestamps;
759 int currentTimestampPairIndex = 0;
760};
761
762class QRhiGles2 : public QRhiImplementation
763{
764public:
765 QRhiGles2(QRhiGles2InitParams *params, QRhiGles2NativeHandles *importDevice = nullptr);
766
767 bool create(QRhi::Flags flags) override;
768 void destroy() override;
769
770 QRhiGraphicsPipeline *createGraphicsPipeline() override;
771 QRhiComputePipeline *createComputePipeline() override;
772 QRhiShaderResourceBindings *createShaderResourceBindings() override;
773 QRhiBuffer *createBuffer(QRhiBuffer::Type type,
774 QRhiBuffer::UsageFlags usage,
775 quint32 size) override;
776 QRhiRenderBuffer *createRenderBuffer(QRhiRenderBuffer::Type type,
777 const QSize &pixelSize,
778 int sampleCount,
779 QRhiRenderBuffer::Flags flags,
780 QRhiTexture::Format backingFormatHint) override;
781 QRhiTexture *createTexture(QRhiTexture::Format format,
782 const QSize &pixelSize,
783 int depth,
784 int arraySize,
785 int sampleCount,
786 QRhiTexture::Flags flags) override;
787 QRhiSampler *createSampler(QRhiSampler::Filter magFilter,
788 QRhiSampler::Filter minFilter,
789 QRhiSampler::Filter mipmapMode,
790 QRhiSampler:: AddressMode u,
791 QRhiSampler::AddressMode v,
792 QRhiSampler::AddressMode w) override;
793
794 QRhiTextureRenderTarget *createTextureRenderTarget(const QRhiTextureRenderTargetDescription &desc,
795 QRhiTextureRenderTarget::Flags flags) override;
796
797 QRhiSwapChain *createSwapChain() override;
798 QRhi::FrameOpResult beginFrame(QRhiSwapChain *swapChain, QRhi::BeginFrameFlags flags) override;
799 QRhi::FrameOpResult endFrame(QRhiSwapChain *swapChain, QRhi::EndFrameFlags flags) override;
800 QRhi::FrameOpResult beginOffscreenFrame(QRhiCommandBuffer **cb, QRhi::BeginFrameFlags flags) override;
801 QRhi::FrameOpResult endOffscreenFrame(QRhi::EndFrameFlags flags) override;
802 QRhi::FrameOpResult finish() override;
803
804 void resourceUpdate(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override;
805
806 void beginPass(QRhiCommandBuffer *cb,
807 QRhiRenderTarget *rt,
808 const QColor &colorClearValue,
809 const QRhiDepthStencilClearValue &depthStencilClearValue,
810 QRhiResourceUpdateBatch *resourceUpdates,
811 QRhiCommandBuffer::BeginPassFlags flags) override;
812 void endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override;
813
814 void setGraphicsPipeline(QRhiCommandBuffer *cb,
815 QRhiGraphicsPipeline *ps) override;
816
817 void setShaderResources(QRhiCommandBuffer *cb,
818 QRhiShaderResourceBindings *srb,
819 int dynamicOffsetCount,
820 const QRhiCommandBuffer::DynamicOffset *dynamicOffsets) override;
821
822 void setVertexInput(QRhiCommandBuffer *cb,
823 int startBinding, int bindingCount, const QRhiCommandBuffer::VertexInput *bindings,
824 QRhiBuffer *indexBuf, quint32 indexOffset,
825 QRhiCommandBuffer::IndexFormat indexFormat) override;
826
827 void setViewport(QRhiCommandBuffer *cb, const QRhiViewport &viewport) override;
828 void setScissor(QRhiCommandBuffer *cb, const QRhiScissor &scissor) override;
829 void setBlendConstants(QRhiCommandBuffer *cb, const QColor &c) override;
830 void setStencilRef(QRhiCommandBuffer *cb, quint32 refValue) override;
831
832 void draw(QRhiCommandBuffer *cb, quint32 vertexCount,
833 quint32 instanceCount, quint32 firstVertex, quint32 firstInstance) override;
834
835 void drawIndexed(QRhiCommandBuffer *cb, quint32 indexCount,
836 quint32 instanceCount, quint32 firstIndex,
837 qint32 vertexOffset, quint32 firstInstance) override;
838
839 void debugMarkBegin(QRhiCommandBuffer *cb, const QByteArray &name) override;
840 void debugMarkEnd(QRhiCommandBuffer *cb) override;
841 void debugMarkMsg(QRhiCommandBuffer *cb, const QByteArray &msg) override;
842
843 void beginComputePass(QRhiCommandBuffer *cb,
844 QRhiResourceUpdateBatch *resourceUpdates,
845 QRhiCommandBuffer::BeginPassFlags flags) override;
846 void endComputePass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override;
847 void setComputePipeline(QRhiCommandBuffer *cb, QRhiComputePipeline *ps) override;
848 void dispatch(QRhiCommandBuffer *cb, int x, int y, int z) override;
849
850 const QRhiNativeHandles *nativeHandles(QRhiCommandBuffer *cb) override;
851 void beginExternal(QRhiCommandBuffer *cb) override;
852 void endExternal(QRhiCommandBuffer *cb) override;
853 double lastCompletedGpuTime(QRhiCommandBuffer *cb) override;
854
855 QList<int> supportedSampleCounts() const override;
856 int ubufAlignment() const override;
857 bool isYUpInFramebuffer() const override;
858 bool isYUpInNDC() const override;
859 bool isClipDepthZeroToOne() const override;
860 QMatrix4x4 clipSpaceCorrMatrix() const override;
861 bool isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture::Flags flags) const override;
862 bool isFeatureSupported(QRhi::Feature feature) const override;
863 int resourceLimit(QRhi::ResourceLimit limit) const override;
864 const QRhiNativeHandles *nativeHandles() override;
865 QRhiDriverInfo driverInfo() const override;
866 QRhiStats statistics() override;
867 bool makeThreadLocalNativeContextCurrent() override;
868 void releaseCachedResources() override;
869 bool isDeviceLost() const override;
870
871 QByteArray pipelineCacheData() override;
872 void setPipelineCacheData(const QByteArray &data) override;
873
874 bool ensureContext(QSurface *surface = nullptr) const;
875 QSurface *evaluateFallbackSurface() const;
876 void executeDeferredReleases();
877 void trackedBufferBarrier(QGles2CommandBuffer *cbD, QGles2Buffer *bufD, QGles2Buffer::Access access);
878 void trackedImageBarrier(QGles2CommandBuffer *cbD, QGles2Texture *texD, QGles2Texture::Access access);
879 void enqueueSubresUpload(QGles2Texture *texD, QGles2CommandBuffer *cbD,
880 int layer, int level, const QRhiTextureSubresourceUploadDescription &subresDesc);
881 void enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates);
882 void trackedRegisterBuffer(QRhiPassResourceTracker *passResTracker,
883 QGles2Buffer *bufD,
884 QRhiPassResourceTracker::BufferAccess access,
885 QRhiPassResourceTracker::BufferStage stage);
886 void trackedRegisterTexture(QRhiPassResourceTracker *passResTracker,
887 QGles2Texture *texD,
888 QRhiPassResourceTracker::TextureAccess access,
889 QRhiPassResourceTracker::TextureStage stage);
890 void executeCommandBuffer(QRhiCommandBuffer *cb);
891 void executeBindGraphicsPipeline(QGles2CommandBuffer *cbD, QGles2GraphicsPipeline *psD);
892 void bindCombinedSampler(QGles2CommandBuffer *cbD, QGles2Texture *texD, QGles2Sampler *samplerD,
893 void *ps, uint psGeneration, int glslLocation,
894 int *texUnit, bool *activeTexUnitAltered);
895 void bindShaderResources(QGles2CommandBuffer *cbD,
896 QRhiGraphicsPipeline *maybeGraphicsPs, QRhiComputePipeline *maybeComputePs,
897 QRhiShaderResourceBindings *srb,
898 const uint *dynOfsPairs, int dynOfsCount);
899 QGles2RenderTargetData *enqueueBindFramebuffer(QRhiRenderTarget *rt, QGles2CommandBuffer *cbD,
900 bool *wantsColorClear = nullptr, bool *wantsDsClear = nullptr);
901 void enqueueBarriersForPass(QGles2CommandBuffer *cbD);
902 QByteArray shaderSource(const QRhiShaderStage &shaderStage, QShaderVersion *shaderVersion);
903 bool compileShader(GLuint program, const QRhiShaderStage &shaderStage, QShaderVersion *shaderVersion);
904 bool linkProgram(GLuint program);
905 using ActiveUniformLocationTracker = QDuplicateTracker<int, 32>;
906 void registerUniformIfActive(const QShaderDescription::BlockVariable &var,
907 const QByteArray &namePrefix, int binding, int baseOffset,
908 GLuint program,
909 ActiveUniformLocationTracker *activeUniformLocations,
910 QGles2UniformDescriptionVector *dst);
911 void gatherUniforms(GLuint program, const QShaderDescription::UniformBlock &ub,
912 ActiveUniformLocationTracker *activeUniformLocations, QGles2UniformDescriptionVector *dst);
913 void gatherSamplers(GLuint program, const QShaderDescription::InOutVariable &v,
914 QGles2SamplerDescriptionVector *dst);
915 void gatherGeneratedSamplers(GLuint program,
916 const QShader::SeparateToCombinedImageSamplerMapping &mapping,
917 QGles2SamplerDescriptionVector *dst);
918 void sanityCheckVertexFragmentInterface(const QShaderDescription &vsDesc, const QShaderDescription &fsDesc);
919 bool isProgramBinaryDiskCacheEnabled() const;
920
921 enum ProgramCacheResult {
922 ProgramCacheHit,
923 ProgramCacheMiss,
924 ProgramCacheError
925 };
926 ProgramCacheResult tryLoadFromDiskOrPipelineCache(const QRhiShaderStage *stages,
927 int stageCount,
928 GLuint program,
929 const QVector<QShaderDescription::InOutVariable> &inputVars,
930 QByteArray *cacheKey);
931 void trySaveToDiskCache(GLuint program, const QByteArray &cacheKey);
932 void trySaveToPipelineCache(GLuint program, const QByteArray &cacheKey, bool force = false);
933
934 QRhi::Flags rhiFlags;
935 QOpenGLContext *ctx = nullptr;
936 bool importedContext = false;
937 QSurfaceFormat requestedFormat;
938 QSurface *fallbackSurface = nullptr;
939 QPointer<QWindow> maybeWindow = nullptr;
940 QOpenGLContext *maybeShareContext = nullptr;
941 mutable bool needsMakeCurrentDueToSwap = false;
942 QOpenGLExtensions *f = nullptr;
943 void (QOPENGLF_APIENTRYP glPolygonMode) (GLenum, GLenum) = nullptr;
944 void(QOPENGLF_APIENTRYP glTexImage1D)(GLenum, GLint, GLint, GLsizei, GLint, GLenum, GLenum,
945 const void *) = nullptr;
946 void(QOPENGLF_APIENTRYP glTexStorage1D)(GLenum, GLint, GLenum, GLsizei) = nullptr;
947 void(QOPENGLF_APIENTRYP glTexSubImage1D)(GLenum, GLint, GLint, GLsizei, GLenum, GLenum,
948 const GLvoid *) = nullptr;
949 void(QOPENGLF_APIENTRYP glCopyTexSubImage1D)(GLenum, GLint, GLint, GLint, GLint,
950 GLsizei) = nullptr;
951 void(QOPENGLF_APIENTRYP glCompressedTexImage1D)(GLenum, GLint, GLenum, GLsizei, GLint, GLsizei,
952 const GLvoid *) = nullptr;
953 void(QOPENGLF_APIENTRYP glCompressedTexSubImage1D)(GLenum, GLint, GLint, GLsizei, GLenum,
954 GLsizei, const GLvoid *) = nullptr;
955 void(QOPENGLF_APIENTRYP glFramebufferTexture1D)(GLenum, GLenum, GLenum, GLuint,
956 GLint) = nullptr;
957 void(QOPENGLF_APIENTRYP glFramebufferTextureMultiviewOVR)(GLenum, GLenum, GLuint, GLint,
958 GLint, GLsizei) = nullptr;
959 void (QOPENGLF_APIENTRYP glQueryCounter)(GLuint, GLenum) = nullptr;
960 void (QOPENGLF_APIENTRYP glGetQueryObjectui64v)(GLuint, GLenum, quint64 *) = nullptr;
961 void (QOPENGLF_APIENTRYP glObjectLabel)(GLenum, GLuint, GLsizei, const GLchar *) = nullptr;
962 void (QOPENGLF_APIENTRYP glFramebufferTexture2DMultisampleEXT)(GLenum, GLenum, GLenum, GLuint, GLint, GLsizei) = nullptr;
963 void (QOPENGLF_APIENTRYP glFramebufferTextureMultisampleMultiviewOVR)(GLenum, GLenum, GLuint, GLint, GLsizei, GLint, GLsizei) = nullptr;
964 uint vao = 0;
965 struct Caps {
966 Caps()
967 : ctxMajor(2),
968 ctxMinor(0),
969 maxTextureSize(2048),
970 maxDrawBuffers(4),
971 maxSamples(16),
972 maxTextureArraySize(0),
973 maxThreadGroupsPerDimension(0),
974 maxThreadsPerThreadGroup(0),
975 maxThreadGroupsX(0),
976 maxThreadGroupsY(0),
977 maxThreadGroupsZ(0),
978 maxUniformVectors(4096),
979 maxVertexInputs(8),
980 maxVertexOutputs(8),
981 msaaRenderBuffer(false),
982 multisampledTexture(false),
983 npotTextureFull(true),
984 gles(false),
985 fixedIndexPrimitiveRestart(false),
986 bgraExternalFormat(false),
987 bgraInternalFormat(false),
988 r8Format(false),
989 r16Format(false),
990 floatFormats(false),
991 rgb10Formats(false),
992 depthTexture(false),
993 packedDepthStencil(false),
994 needsDepthStencilCombinedAttach(false),
995 srgbWriteControl(false),
996 coreProfile(false),
997 uniformBuffers(false),
998 elementIndexUint(false),
999 depth24(false),
1000 rgba8Format(false),
1001 instancing(false),
1002 baseVertex(false),
1003 compute(false),
1004 textureCompareMode(false),
1005 properMapBuffer(false),
1006 nonBaseLevelFramebufferTexture(false),
1007 texelFetch(false),
1008 intAttributes(true),
1009 screenSpaceDerivatives(false),
1010 programBinary(false),
1011 texture3D(false),
1012 tessellation(false),
1013 geometryShader(false),
1014 texture1D(false),
1015 hasDrawBuffersFunc(false),
1016 halfAttributes(false),
1017 multiView(false),
1018 timestamps(false),
1019 objectLabel(false),
1020 glesMultisampleRenderToTexture(false),
1021 glesMultiviewMultisampleRenderToTexture(false),
1022 unpackRowLength(false)
1023 { }
1024 int ctxMajor;
1025 int ctxMinor;
1026 int maxTextureSize;
1027 int maxDrawBuffers;
1028 int maxSamples;
1029 int maxTextureArraySize;
1030 int maxThreadGroupsPerDimension;
1031 int maxThreadsPerThreadGroup;
1032 int maxThreadGroupsX;
1033 int maxThreadGroupsY;
1034 int maxThreadGroupsZ;
1035 int maxUniformVectors;
1036 int maxVertexInputs;
1037 int maxVertexOutputs;
1038 // Multisample fb and blit are supported (GLES 3.0 or OpenGL 3.x). Not
1039 // the same as multisample textures!
1040 uint msaaRenderBuffer : 1;
1041 uint multisampledTexture : 1;
1042 uint npotTextureFull : 1;
1043 uint gles : 1;
1044 uint fixedIndexPrimitiveRestart : 1;
1045 uint bgraExternalFormat : 1;
1046 uint bgraInternalFormat : 1;
1047 uint r8Format : 1;
1048 uint r16Format : 1;
1049 uint floatFormats : 1;
1050 uint rgb10Formats : 1;
1051 uint depthTexture : 1;
1052 uint packedDepthStencil : 1;
1053 uint needsDepthStencilCombinedAttach : 1;
1054 uint srgbWriteControl : 1;
1055 uint coreProfile : 1;
1056 uint uniformBuffers : 1;
1057 uint elementIndexUint : 1;
1058 uint depth24 : 1;
1059 uint rgba8Format : 1;
1060 uint instancing : 1;
1061 uint baseVertex : 1;
1062 uint compute : 1;
1063 uint textureCompareMode : 1;
1064 uint properMapBuffer : 1;
1065 uint nonBaseLevelFramebufferTexture : 1;
1066 uint texelFetch : 1;
1067 uint intAttributes : 1;
1068 uint screenSpaceDerivatives : 1;
1069 uint programBinary : 1;
1070 uint texture3D : 1;
1071 uint tessellation : 1;
1072 uint geometryShader : 1;
1073 uint texture1D : 1;
1074 uint hasDrawBuffersFunc : 1;
1075 uint halfAttributes : 1;
1076 uint multiView : 1;
1077 uint timestamps : 1;
1078 uint objectLabel : 1;
1079 uint glesMultisampleRenderToTexture : 1;
1080 uint glesMultiviewMultisampleRenderToTexture : 1;
1081 uint unpackRowLength : 1;
1082 } caps;
1083 QGles2SwapChain *currentSwapChain = nullptr;
1084 QSet<GLint> supportedCompressedFormats;
1085 mutable QList<int> supportedSampleCountList;
1086 QRhiGles2NativeHandles nativeHandlesStruct;
1087 QRhiDriverInfo driverInfoStruct;
1088 mutable bool contextLost = false;
1089
1090 struct DeferredReleaseEntry {
1091 enum Type {
1092 Buffer,
1093 Pipeline,
1094 Texture,
1095 RenderBuffer,
1096 TextureRenderTarget
1097 };
1098 Type type;
1099 union {
1100 struct {
1101 GLuint buffer;
1102 } buffer;
1103 struct {
1104 GLuint program;
1105 } pipeline;
1106 struct {
1107 GLuint texture;
1108 } texture;
1109 struct {
1110 GLuint renderbuffer;
1111 GLuint renderbuffer2;
1112 } renderbuffer;
1113 struct {
1114 GLuint framebuffer;
1115 GLuint nonMsaaThrowawayDepthTexture;
1116 } textureRenderTarget;
1117 };
1118 };
1119 QList<DeferredReleaseEntry> releaseQueue;
1120
1121 struct OffscreenFrame {
1122 OffscreenFrame(QRhiImplementation *rhi) : cbWrapper(rhi) { }
1123 bool active = false;
1124 QGles2CommandBuffer cbWrapper;
1125 GLuint tsQueries[2] = {};
1126 } ofr;
1127
1128 QHash<QRhiShaderStage, uint> m_shaderCache;
1129
1130 struct PipelineCacheData {
1131 quint32 format;
1132 QByteArray data;
1133 };
1134 QHash<QByteArray, PipelineCacheData> m_pipelineCache;
1135
1136 struct Scratch {
1137 union data32_t {
1138 float f;
1139 qint32 i;
1140 };
1141 QVarLengthArray<data32_t, 128> packedArray;
1142 struct SeparateTexture {
1143 QGles2Texture *texture;
1144 int binding;
1145 int elem;
1146 };
1147 QVarLengthArray<SeparateTexture, 8> separateTextureBindings;
1148 struct SeparateSampler {
1149 QGles2Sampler *sampler;
1150 int binding;
1151 };
1152 QVarLengthArray<SeparateSampler, 4> separateSamplerBindings;
1153 } m_scratch;
1154};
1155
1156Q_DECLARE_TYPEINFO(QRhiGles2::DeferredReleaseEntry, Q_RELOCATABLE_TYPE);
1157
1158QT_END_NAMESPACE
1159
1160#endif
1161

Provided by KDAB

Privacy Policy
Learn Advanced QML with KDAB
Find out more

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