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 57 QT_BEGIN_NAMESPACE 58 59 class QOpenGLExtensions; 60 61 struct 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 89 struct 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 104 struct 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 114 inline 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 124 inline bool operator!=(const QGles2SamplerData &a, const QGles2SamplerData &b) 125 { 126 return !(a == b); 127 } 128 129 struct 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 171 struct 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 184 struct QGles2RenderPassDescriptor : public QRhiRenderPassDescriptor 185 { 186 QGles2RenderPassDescriptor(QRhiImplementation *rhi); 187 ~QGles2RenderPassDescriptor(); 188 void release() override; 189 bool isCompatible(const QRhiRenderPassDescriptor *other) const override; 190 }; 191 192 struct QGles2RenderTargetData 193 { QGles2RenderTargetDataQGles2RenderTargetData194 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 205 struct 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 218 struct 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 236 struct 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 247 struct QGles2UniformDescription 248 { 249 QShaderDescription::VariableType type; 250 int glslLocation; 251 int binding; 252 uint offset; 253 int size; 254 int arrayDim; 255 }; 256 257 Q_DECLARE_TYPEINFO(QGles2UniformDescription, Q_MOVABLE_TYPE); 258 259 struct QGles2SamplerDescription 260 { 261 int glslLocation; 262 int binding; 263 }; 264 265 Q_DECLARE_TYPEINFO(QGles2SamplerDescription, Q_MOVABLE_TYPE); 266 267 struct 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 282 struct 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 296 struct 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; resetQGles2CommandBuffer::GraphicsPassState557 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; resetQGles2CommandBuffer::ComputePassState570 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) retainDataQGles2CommandBuffer579 const void *retainData(const QByteArray &data) { 580 dataRetainPool.append(data); 581 return dataRetainPool.constLast().constData(); 582 } retainImageQGles2CommandBuffer583 const void *retainImage(const QImage &image) { 584 imageRetainPool.append(image); 585 return imageRetainPool.constLast().constBits(); 586 } resetCommandsQGles2CommandBuffer587 void resetCommands() { 588 commands.clear(); 589 dataRetainPool.clear(); 590 imageRetainPool.clear(); 591 592 passResTrackers.clear(); 593 currentPassResTrackerIndex = -1; 594 } resetStateQGles2CommandBuffer595 void resetState() { 596 recordingPass = NoPass; 597 currentTarget = nullptr; 598 resetCommands(); 599 resetCachedState(); 600 } resetCachedStateQGles2CommandBuffer601 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 613 Q_DECLARE_TYPEINFO(QGles2CommandBuffer::Command, Q_MOVABLE_TYPE); 614 615 inline 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 624 inline bool operator!=(const QGles2CommandBuffer::GraphicsPassState::StencilFace &a, 625 const QGles2CommandBuffer::GraphicsPassState::StencilFace &b) 626 { 627 return !(a == b); 628 } 629 630 inline 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 636 inline bool operator!=(const QGles2CommandBuffer::GraphicsPassState::ColorMask &a, 637 const QGles2CommandBuffer::GraphicsPassState::ColorMask &b) 638 { 639 return !(a == b); 640 } 641 642 inline 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 653 inline bool operator!=(const QGles2CommandBuffer::GraphicsPassState::Blend &a, 654 const QGles2CommandBuffer::GraphicsPassState::Blend &b) 655 { 656 return !(a == b); 657 } 658 659 struct 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 680 class QRhiGles2 : public QRhiImplementation 681 { 682 public: 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 { CapsCaps839 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 { OffscreenFrameOffscreenFrame940 OffscreenFrame(QRhiImplementation *rhi) : cbWrapper(rhi) { } 941 bool active = false; 942 QGles2CommandBuffer cbWrapper; 943 } ofr; 944 945 QHash<QRhiShaderStage, uint> m_shaderCache; 946 }; 947 948 Q_DECLARE_TYPEINFO(QRhiGles2::DeferredReleaseEntry, Q_MOVABLE_TYPE); 949 950 QT_END_NAMESPACE 951 952 #endif 953