Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qrhinull.cpp
Go to the documentation of this file.
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// Qt-Security score:significant reason:default
4
5#include "qrhinull_p.h"
6#include <qmath.h>
7#include <QPainter>
8
10
11/*!
12 \class QRhiNullInitParams
13 \inmodule QtGuiPrivate
14 \inheaderfile rhi/qrhi.h
15 \since 6.6
16 \brief Null backend specific initialization parameters.
17
18 \note This is a RHI API with limited compatibility guarantees, see \l QRhi
19 for details.
20
21 A Null QRhi needs no special parameters for initialization.
22
23 \badcode
24 QRhiNullInitParams params;
25 rhi = QRhi::create(QRhi::Null, &params);
26 \endcode
27
28 The Null backend does not issue any graphics calls and creates no
29 resources. All QRhi operations will succeed as normal so applications can
30 still be run, albeit potentially at an unthrottled speed, depending on
31 their frame rendering strategy.
32 */
33
34/*!
35 \class QRhiNullNativeHandles
36 \inmodule QtGuiPrivate
37 \inheaderfile rhi/qrhi.h
38 \since 6.6
39 \brief Empty.
40
41 \note This is a RHI API with limited compatibility guarantees, see \l QRhi
42 for details.
43 */
44
45QRhiNull::QRhiNull(QRhiNullInitParams *params)
46 : offscreenCommandBuffer(this)
47{
48 Q_UNUSED(params);
49}
50
51bool QRhiNull::create(QRhi::Flags flags)
52{
53 Q_UNUSED(flags);
54 return true;
55}
56
58{
59}
60
62{
63 return { 1 };
64}
65
66QList<QSize> QRhiNull::supportedShadingRates(int sampleCount) const
67{
68 Q_UNUSED(sampleCount);
69 return { QSize(1, 1) };
70}
71
72QRhiSwapChain *QRhiNull::createSwapChain()
73{
74 return new QNullSwapChain(this);
75}
76
77QRhiBuffer *QRhiNull::createBuffer(QRhiBuffer::Type type, QRhiBuffer::UsageFlags usage, quint32 size)
78{
79 return new QNullBuffer(this, type, usage, size);
80}
81
83{
84 return 256;
85}
86
88{
89 return false;
90}
91
92bool QRhiNull::isYUpInNDC() const
93{
94 return true;
95}
96
98{
99 return true;
100}
101
103{
104 return QMatrix4x4(); // identity
105}
106
107bool QRhiNull::isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture::Flags flags) const
108{
109 Q_UNUSED(format);
110 Q_UNUSED(flags);
111 return true;
112}
113
114bool QRhiNull::isFeatureSupported(QRhi::Feature feature) const
115{
116 Q_UNUSED(feature);
117 return true;
118}
119
120int QRhiNull::resourceLimit(QRhi::ResourceLimit limit) const
121{
122 switch (limit) {
123 case QRhi::TextureSizeMin:
124 return 1;
125 case QRhi::TextureSizeMax:
126 return 16384;
127 case QRhi::MaxColorAttachments:
128 return 8;
129 case QRhi::FramesInFlight:
130 return 1;
131 case QRhi::MaxAsyncReadbackFrames:
132 return 1;
133 case QRhi::MaxThreadGroupsPerDimension:
134 return 0;
135 case QRhi::MaxThreadsPerThreadGroup:
136 return 0;
137 case QRhi::MaxThreadGroupX:
138 return 0;
139 case QRhi::MaxThreadGroupY:
140 return 0;
141 case QRhi::MaxThreadGroupZ:
142 return 0;
143 case QRhi::TextureArraySizeMax:
144 return 2048;
145 case QRhi::MaxUniformBufferRange:
146 return 65536;
147 case QRhi::MaxVertexInputs:
148 return 32;
149 case QRhi::MaxVertexOutputs:
150 return 32;
151 case QRhi::MaxPushConstantsSize:
152 return 128;
153 case QRhi::MaxVertexStorageBuffers:
154 case QRhi::MaxFragmentStorageBuffers:
155 return 32;
156 case QRhi::ShadingRateImageTileSize:
157 return 0;
158 }
159
160 Q_UNREACHABLE_RETURN(0);
161}
162
164{
165 return &nativeHandlesStruct;
166}
167
169{
170 QRhiDriverInfo info;
171 info.deviceName = QByteArrayLiteral("Null");
172 return info;
173}
174
176{
177 return {};
178}
179
181{
182 // not applicable
183 return false;
184}
185
186void QRhiNull::setQueueSubmitParams(QRhiNativeHandles *)
187{
188 // not applicable
189}
190
192{
193 // nothing to do here
194}
195
197{
198 return false;
199}
200
202{
203 return QByteArray();
204}
205
206void QRhiNull::setPipelineCacheData(const QByteArray &data)
207{
208 Q_UNUSED(data);
209}
210
211QRhiRenderBuffer *QRhiNull::createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize,
212 int sampleCount, QRhiRenderBuffer::Flags flags,
213 QRhiTexture::Format backingFormatHint)
214{
215 return new QNullRenderBuffer(this, type, pixelSize, sampleCount, flags, backingFormatHint);
216}
217
218QRhiTexture *QRhiNull::createTexture(QRhiTexture::Format format,
219 const QSize &pixelSize, int depth, int arraySize,
220 int sampleCount, QRhiTexture::Flags flags)
221{
222 return new QNullTexture(this, format, pixelSize, depth, arraySize, sampleCount, flags);
223}
224
225QRhiSampler *QRhiNull::createSampler(QRhiSampler::Filter magFilter, QRhiSampler::Filter minFilter,
226 QRhiSampler::Filter mipmapMode,
227 QRhiSampler::AddressMode u, QRhiSampler::AddressMode v, QRhiSampler::AddressMode w)
228{
229 return new QNullSampler(this, magFilter, minFilter, mipmapMode, u, v, w);
230}
231
232QRhiTextureRenderTarget *QRhiNull::createTextureRenderTarget(const QRhiTextureRenderTargetDescription &desc,
233 QRhiTextureRenderTarget::Flags flags)
234{
235 return new QNullTextureRenderTarget(this, desc, flags);
236}
237
238QRhiShadingRateMap *QRhiNull::createShadingRateMap()
239{
240 return nullptr;
241}
242
244{
245 return new QNullGraphicsPipeline(this);
246}
247
249{
250 return new QNullComputePipeline(this);
251}
252
254{
255 return new QNullShaderResourceBindings(this);
256}
257
258void QRhiNull::setGraphicsPipeline(QRhiCommandBuffer *cb, QRhiGraphicsPipeline *ps)
259{
260 Q_UNUSED(cb);
261 Q_UNUSED(ps);
262}
263
264void QRhiNull::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBindings *srb,
265 int dynamicOffsetCount,
266 const QRhiCommandBuffer::DynamicOffset *dynamicOffsets)
267{
268 Q_UNUSED(cb);
269 Q_UNUSED(srb);
270 Q_UNUSED(dynamicOffsetCount);
271 Q_UNUSED(dynamicOffsets);
272}
273
274void QRhiNull::setVertexInput(QRhiCommandBuffer *cb,
275 int startBinding, int bindingCount, const QRhiCommandBuffer::VertexInput *bindings,
276 QRhiBuffer *indexBuf, quint32 indexOffset, QRhiCommandBuffer::IndexFormat indexFormat)
277{
278 Q_UNUSED(cb);
279 Q_UNUSED(startBinding);
280 Q_UNUSED(bindingCount);
281 Q_UNUSED(bindings);
282 Q_UNUSED(indexBuf);
283 Q_UNUSED(indexOffset);
284 Q_UNUSED(indexFormat);
285}
286
287void QRhiNull::setViewport(QRhiCommandBuffer *cb, const QRhiViewport &viewport)
288{
289 Q_UNUSED(cb);
290 Q_UNUSED(viewport);
291}
292
293void QRhiNull::setScissor(QRhiCommandBuffer *cb, const QRhiScissor &scissor)
294{
295 Q_UNUSED(cb);
296 Q_UNUSED(scissor);
297}
298
299void QRhiNull::setBlendConstants(QRhiCommandBuffer *cb, const QColor &c)
300{
301 Q_UNUSED(cb);
302 Q_UNUSED(c);
303}
304
305void QRhiNull::setStencilRef(QRhiCommandBuffer *cb, quint32 refValue)
306{
307 Q_UNUSED(cb);
308 Q_UNUSED(refValue);
309}
310
311void QRhiNull::setPushConstants(QRhiCommandBuffer *cb, quint32 offset, quint32 size, const void *data)
312{
313 Q_UNUSED(cb);
314 Q_UNUSED(offset);
315 Q_UNUSED(size);
316 Q_UNUSED(data);
317}
318
319void QRhiNull::setShadingRate(QRhiCommandBuffer *cb, const QSize &coarsePixelSize)
320{
321 Q_UNUSED(cb);
322 Q_UNUSED(coarsePixelSize);
323}
324
325void QRhiNull::draw(QRhiCommandBuffer *cb, quint32 vertexCount,
326 quint32 instanceCount, quint32 firstVertex, quint32 firstInstance)
327{
328 Q_UNUSED(cb);
329 Q_UNUSED(vertexCount);
330 Q_UNUSED(instanceCount);
331 Q_UNUSED(firstVertex);
332 Q_UNUSED(firstInstance);
333}
334
335void QRhiNull::drawIndexed(QRhiCommandBuffer *cb, quint32 indexCount,
336 quint32 instanceCount, quint32 firstIndex, qint32 vertexOffset, quint32 firstInstance)
337{
338 Q_UNUSED(cb);
339 Q_UNUSED(indexCount);
340 Q_UNUSED(instanceCount);
341 Q_UNUSED(firstIndex);
342 Q_UNUSED(vertexOffset);
343 Q_UNUSED(firstInstance);
344}
345
346void QRhiNull::drawIndirect(QRhiCommandBuffer *cb, QRhiBuffer *indirectBuffer,
347 quint32 indirectBufferOffset, quint32 drawCount, quint32 stride)
348{
349 Q_UNUSED(cb);
350 Q_UNUSED(indirectBuffer);
351 Q_UNUSED(indirectBufferOffset);
352 Q_UNUSED(drawCount);
353 Q_UNUSED(stride);
354}
355
356void QRhiNull::drawIndexedIndirect(QRhiCommandBuffer *cb, QRhiBuffer *indirectBuffer,
357 quint32 indirectBufferOffset, quint32 drawCount, quint32 stride)
358{
359 Q_UNUSED(cb);
360 Q_UNUSED(indirectBuffer);
361 Q_UNUSED(indirectBufferOffset);
362 Q_UNUSED(drawCount);
363 Q_UNUSED(stride);
364}
365
366void QRhiNull::drawIndirectCount(QRhiCommandBuffer *cb,
367 QRhiBuffer *indirectBuffer, quint32 indirectBufferOffset,
368 QRhiBuffer *countBuffer, quint32 countBufferOffset,
369 quint32 maxDrawCount, quint32 stride)
370{
371 Q_UNUSED(cb);
372 Q_UNUSED(indirectBuffer);
373 Q_UNUSED(indirectBufferOffset);
374 Q_UNUSED(countBuffer);
375 Q_UNUSED(countBufferOffset);
376 Q_UNUSED(maxDrawCount);
377 Q_UNUSED(stride);
378}
379
380void QRhiNull::drawIndexedIndirectCount(QRhiCommandBuffer *cb,
381 QRhiBuffer *indirectBuffer, quint32 indirectBufferOffset,
382 QRhiBuffer *countBuffer, quint32 countBufferOffset,
383 quint32 maxDrawCount, quint32 stride)
384{
385 Q_UNUSED(cb);
386 Q_UNUSED(indirectBuffer);
387 Q_UNUSED(indirectBufferOffset);
388 Q_UNUSED(countBuffer);
389 Q_UNUSED(countBufferOffset);
390 Q_UNUSED(maxDrawCount);
391 Q_UNUSED(stride);
392}
393
394void QRhiNull::debugMarkBegin(QRhiCommandBuffer *cb, const QByteArray &name)
395{
396 Q_UNUSED(cb);
397 Q_UNUSED(name);
398}
399
400void QRhiNull::debugMarkEnd(QRhiCommandBuffer *cb)
401{
402 Q_UNUSED(cb);
403}
404
405void QRhiNull::debugMarkMsg(QRhiCommandBuffer *cb, const QByteArray &msg)
406{
407 Q_UNUSED(cb);
408 Q_UNUSED(msg);
409}
410
411void QRhiNull::setComputePipeline(QRhiCommandBuffer *cb, QRhiComputePipeline *ps)
412{
413 Q_UNUSED(cb);
414 Q_UNUSED(ps);
415}
416
417void QRhiNull::dispatch(QRhiCommandBuffer *cb, int x, int y, int z)
418{
419 Q_UNUSED(cb);
420 Q_UNUSED(x);
421 Q_UNUSED(y);
422 Q_UNUSED(z);
423}
424
425void QRhiNull::dispatchIndirect(QRhiCommandBuffer *cb, QRhiBuffer *indirectBuffer,
426 quint32 indirectBufferOffset)
427{
428 Q_UNUSED(cb);
429 Q_UNUSED(indirectBuffer);
430 Q_UNUSED(indirectBufferOffset);
431}
432
433const QRhiNativeHandles *QRhiNull::nativeHandles(QRhiCommandBuffer *cb)
434{
435 Q_UNUSED(cb);
436 return nullptr;
437}
438
439void QRhiNull::beginExternal(QRhiCommandBuffer *cb)
440{
441 Q_UNUSED(cb);
442}
443
444void QRhiNull::endExternal(QRhiCommandBuffer *cb)
445{
446 Q_UNUSED(cb);
447}
448
449double QRhiNull::lastCompletedGpuTime(QRhiCommandBuffer *cb)
450{
451 Q_UNUSED(cb);
452 return 0;
453}
454
455QRhi::FrameOpResult QRhiNull::beginFrame(QRhiSwapChain *swapChain, QRhi::BeginFrameFlags flags)
456{
457 Q_UNUSED(flags);
458 currentSwapChain = swapChain;
459 return QRhi::FrameOpSuccess;
460}
461
462QRhi::FrameOpResult QRhiNull::endFrame(QRhiSwapChain *swapChain, QRhi::EndFrameFlags flags)
463{
464 Q_UNUSED(flags);
465 QNullSwapChain *swapChainD = QRHI_RES(QNullSwapChain, swapChain);
466 swapChainD->frameCount += 1;
467 currentSwapChain = nullptr;
468 return QRhi::FrameOpSuccess;
469}
470
471QRhi::FrameOpResult QRhiNull::beginOffscreenFrame(QRhiCommandBuffer **cb, QRhi::BeginFrameFlags flags)
472{
473 Q_UNUSED(flags);
474 *cb = &offscreenCommandBuffer;
475 return QRhi::FrameOpSuccess;
476}
477
478QRhi::FrameOpResult QRhiNull::endOffscreenFrame(QRhi::EndFrameFlags flags)
479{
480 Q_UNUSED(flags);
481 return QRhi::FrameOpSuccess;
482}
483
485{
486 return QRhi::FrameOpSuccess;
487}
488
490{
491 QNullTexture *texD = QRHI_RES(QNullTexture, u.dst);
492 for (const auto &subres : u.subresDesc) {
493 const int layer = subres.layer;
494 const int level = subres.level;
495 const QRhiTextureSubresourceUploadDescription &subresDesc(subres.desc);
496 if (!subresDesc.image().isNull()) {
497 const QImage src = subresDesc.image();
498 QPainter painter(&texD->image[layer][level]);
499 const QSize srcSize = subresDesc.sourceSize().isEmpty()
500 ? src.size() : subresDesc.sourceSize();
501 painter.setCompositionMode(QPainter::CompositionMode_Source);
502 painter.drawImage(subresDesc.destinationTopLeft(), src,
503 QRect(subresDesc.sourceTopLeft(), srcSize));
504 } else if (!subresDesc.data().isEmpty()) {
505 const QSize subresSize = q->sizeForMipLevel(level, texD->pixelSize());
506 int w = subresSize.width();
507 int h = subresSize.height();
508 if (!subresDesc.sourceSize().isEmpty()) {
509 w = subresDesc.sourceSize().width();
510 h = subresDesc.sourceSize().height();
511 }
512 // sourceTopLeft is not supported on this path as per QRhi docs
513 const QByteArray srcData = subresDesc.data();
514 const QPoint dstOffset = subresDesc.destinationTopLeft();
515 QSize size = clampedSubResourceUploadSize(QSize(w, h), dstOffset, level,
516 texD->pixelSize());
517 size = clampedSubResourceUploadSizeForSourceData(size, subresDesc.dataStride(),
518 4, srcData.size());
519 if (size.isEmpty())
520 continue;
521 w = size.width();
522 h = size.height();
523 const char *src = srcData.constData();
524 const int srcBpl = w * 4;
525 int srcStride = srcBpl;
526 if (subresDesc.dataStride())
527 srcStride = subresDesc.dataStride();
528 uchar *dst = texD->image[layer][level].bits();
529 const int dstBpl = texD->image[layer][level].bytesPerLine();
530 for (int y = 0; y < h; ++y) {
531 memcpy(dst + dstOffset.x() * 4 + (y + dstOffset.y()) * dstBpl,
532 src + y * srcStride,
533 size_t(srcBpl));
534 }
535 }
536 }
537}
538
540{
541 QNullTexture *srcD = QRHI_RES(QNullTexture, u.src);
542 QNullTexture *dstD = QRHI_RES(QNullTexture, u.dst);
543 const QImage &srcImage(srcD->image[u.desc.sourceLayer()][u.desc.sourceLevel()]);
544 QImage &dstImage(dstD->image[u.desc.destinationLayer()][u.desc.destinationLevel()]);
545 const QPoint dstPos = u.desc.destinationTopLeft();
546 const QSize size = u.desc.pixelSize().isEmpty() ? srcD->pixelSize() : u.desc.pixelSize();
547 const QPoint srcPos = u.desc.sourceTopLeft();
548
549 QPainter painter(&dstImage);
550 painter.setCompositionMode(QPainter::CompositionMode_Source);
551 painter.drawImage(QRect(dstPos, size), srcImage, QRect(srcPos, size));
552}
553
555{
556 QNullTexture *texD = QRHI_RES(QNullTexture, u.dst);
557 const QSize baseSize = texD->pixelSize();
558 const int levelCount = q->mipLevelsForSize(baseSize);
559 for (int level = 1; level < levelCount; ++level)
560 texD->image[0][level] = texD->image[0][0].scaled(q->sizeForMipLevel(level, baseSize));
561}
562
563void QRhiNull::resourceUpdate(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates)
564{
565 Q_UNUSED(cb);
567 for (int opIdx = 0; opIdx < ud->activeBufferOpCount; ++opIdx) {
568 const QRhiResourceUpdateBatchPrivate::BufferOp &u(ud->bufferOps[opIdx]);
571 {
572 QNullBuffer *bufD = QRHI_RES(QNullBuffer, u.buf);
573 memcpy(bufD->data + u.offset, u.data.constData(), size_t(u.data.size()));
575 QRhiReadbackResult *result = u.result;
576 result->data.resize(u.readSize);
577 QNullBuffer *bufD = QRHI_RES(QNullBuffer, u.buf);
578 memcpy(result->data.data(), bufD->data + u.offset, size_t(u.readSize));
579 if (result->completed)
580 result->completed();
582 QNullBuffer *dstD = QRHI_RES(QNullBuffer, u.buf);
583 QNullBuffer *srcD = QRHI_RES(QNullBuffer, u.src);
584 memcpy(dstD->data + u.offset, srcD->data + u.srcOffset, size_t(u.readSize));
586 QNullBuffer *bufD = QRHI_RES(QNullBuffer, u.buf);
587 memset(bufD->data + u.offset, u.fillValue, size_t(u.readSize));
588 }
589 }
590 for (int opIdx = 0; opIdx < ud->activeTextureOpCount; ++opIdx) {
591 const QRhiResourceUpdateBatchPrivate::TextureOp &u(ud->textureOps[opIdx]);
593 if (u.dst->format() == QRhiTexture::RGBA8)
596 if (u.src->format() == QRhiTexture::RGBA8 && u.dst->format() == QRhiTexture::RGBA8)
599 QRhiReadbackResult *result = u.result;
600 QNullTexture *texD = QRHI_RES(QNullTexture, u.rb.texture());
601 if (texD) {
602 result->format = texD->format();
603 if (u.rb.rect().isValid())
604 result->pixelSize = u.rb.rect().size();
605 else
606 result->pixelSize = q->sizeForMipLevel(u.rb.level(), texD->pixelSize());
607 } else {
608 Q_ASSERT(currentSwapChain);
609 result->format = QRhiTexture::RGBA8;
610 if (u.rb.rect().isValid())
611 result->pixelSize = u.rb.rect().size();
612 else
613 result->pixelSize = currentSwapChain->currentPixelSize();
614 }
615 quint32 bytesPerLine = 0;
616 quint32 byteSize = 0;
617 textureFormatInfo(result->format, result->pixelSize, &bytesPerLine, &byteSize, nullptr);
618 if (texD && texD->format() == QRhiTexture::RGBA8) {
619 result->data.resize(int(byteSize));
620 const QImage &src(texD->image[u.rb.layer()][u.rb.level()]);
621 char *dst = result->data.data();
622 for (int y = 0, h = src.height(); y < h; ++y) {
623 memcpy(dst, src.constScanLine(y), bytesPerLine);
624 dst += bytesPerLine;
625 }
626 } else {
627 result->data.fill(0, int(byteSize));
628 }
629 if (result->completed)
630 result->completed();
632 if (u.dst->format() == QRhiTexture::RGBA8)
634 }
635 }
636 ud->free();
637}
638
639void QRhiNull::beginPass(QRhiCommandBuffer *cb,
640 QRhiRenderTarget *rt,
641 const QColor &colorClearValue,
642 const QRhiDepthStencilClearValue &depthStencilClearValue,
643 QRhiResourceUpdateBatch *resourceUpdates,
644 QRhiCommandBuffer::BeginPassFlags flags)
645{
646 Q_UNUSED(colorClearValue);
647 Q_UNUSED(depthStencilClearValue);
648 Q_UNUSED(flags);
649
650 if (resourceUpdates)
651 resourceUpdate(cb, resourceUpdates);
652
653 if (rt->resourceType() == QRhiRenderTarget::TextureRenderTarget) {
655 if (!QRhiRenderTargetAttachmentTracker::isUpToDate<QNullTexture, QNullRenderBuffer>(rtTex->description(), rtTex->d.currentResIdList))
656 rtTex->create();
657 }
658}
659
660void QRhiNull::endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates)
661{
662 if (resourceUpdates)
663 resourceUpdate(cb, resourceUpdates);
664}
665
666void QRhiNull::beginComputePass(QRhiCommandBuffer *cb,
667 QRhiResourceUpdateBatch *resourceUpdates,
668 QRhiCommandBuffer::BeginPassFlags flags)
669{
670 Q_UNUSED(flags);
671 if (resourceUpdates)
672 resourceUpdate(cb, resourceUpdates);
673}
674
675void QRhiNull::endComputePass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates)
676{
677 if (resourceUpdates)
678 resourceUpdate(cb, resourceUpdates);
679}
680
681QNullBuffer::QNullBuffer(QRhiImplementation *rhi, Type type, UsageFlags usage, quint32 size)
683{
684}
685
690
692{
693 delete[] data;
694 data = nullptr;
695
696 QRHI_RES_RHI(QRhiNull);
697 if (rhiD)
698 rhiD->unregisterResource(this);
699}
700
702{
703 if (data)
704 destroy();
705
706 data = new char[m_size];
707 memset(data, 0, m_size);
708
709 QRHI_RES_RHI(QRhiNull);
710 rhiD->registerResource(this);
711
712 return true;
713}
714
716{
717 Q_ASSERT(m_type == Dynamic);
718 return data;
719}
720
721QNullRenderBuffer::QNullRenderBuffer(QRhiImplementation *rhi, Type type, const QSize &pixelSize,
722 int sampleCount, QRhiRenderBuffer::Flags flags,
723 QRhiTexture::Format backingFormatHint)
725{
726}
727
732
734{
735 valid = false;
736
737 QRHI_RES_RHI(QRhiNull);
738 if (rhiD)
739 rhiD->unregisterResource(this);
740}
741
743{
744 if (valid)
745 destroy();
746
747 valid = true;
748 generation += 1;
749
750 QRHI_RES_RHI(QRhiNull);
751 rhiD->registerResource(this);
752
753 return true;
754}
755
757{
758 return m_type == Color ? QRhiTexture::RGBA8 : QRhiTexture::UnknownFormat;
759}
760
761QNullTexture::QNullTexture(QRhiImplementation *rhi, Format format, const QSize &pixelSize, int depth,
762 int arraySize, int sampleCount, Flags flags)
764{
765}
766
771
773{
774 valid = false;
775
776 QRHI_RES_RHI(QRhiNull);
777 if (rhiD)
778 rhiD->unregisterResource(this);
779}
780
782{
783 if (valid)
784 destroy();
785
786 valid = true;
787
788 QRHI_RES_RHI(QRhiNull);
789 const bool isCube = m_flags.testFlag(CubeMap);
790 const bool is3D = m_flags.testFlag(ThreeDimensional);
791 const bool isArray = m_flags.testFlag(TextureArray);
792 const bool hasMipMaps = m_flags.testFlag(MipMapped);
793 const bool is1D = m_flags.testFlags(OneDimensional);
794 QSize size = is1D ? QSize(qMax(1, m_pixelSize.width()), 1)
795 : (m_pixelSize.isEmpty() ? QSize(1, 1) : m_pixelSize);
796 const int mipLevelCount = hasMipMaps ? rhiD->q->mipLevelsForSize(size) : 1;
797 const int layerCount = is3D ? qMax(1, m_depth)
798 : (isCube ? 6
799 : (isArray ? qMax(0, m_arraySize)
800 : 1));
801
802 if (!rhiD->textureFormatInfo(m_format, size, nullptr, nullptr, nullptr)) {
803 valid = false;
804 return false;
805 }
806
807 if (m_format == RGBA8) {
808 image.resize(layerCount);
809 for (int layer = 0; layer < layerCount; ++layer) {
810 for (int level = 0; level < mipLevelCount; ++level) {
811 image[layer][level] = QImage(rhiD->q->sizeForMipLevel(level, size),
812 QImage::Format_RGBA8888_Premultiplied);
813 image[layer][level].fill(Qt::yellow);
814 }
815 }
816 }
817
818 generation += 1;
819
820 rhiD->registerResource(this);
821
822 return true;
823}
824
825bool QNullTexture::createFrom(QRhiTexture::NativeTexture src)
826{
827 Q_UNUSED(src);
828 if (valid)
829 destroy();
830
831 valid = true;
832
833 generation += 1;
834
835 QRHI_RES_RHI(QRhiNull);
836 rhiD->registerResource(this);
837
838 return true;
839}
840
841QNullSampler::QNullSampler(QRhiImplementation *rhi, Filter magFilter, Filter minFilter, Filter mipmapMode,
842 AddressMode u, AddressMode v, AddressMode w)
844{
845}
846
851
853{
854 QRHI_RES_RHI(QRhiNull);
855 if (rhiD)
856 rhiD->unregisterResource(this);
857}
858
860{
861 QRHI_RES_RHI(QRhiNull);
862 rhiD->registerResource(this);
863 return true;
864}
865
870
875
877{
878 QRHI_RES_RHI(QRhiNull);
879 if (rhiD)
880 rhiD->unregisterResource(this);
881}
882
883bool QNullRenderPassDescriptor::isCompatible(const QRhiRenderPassDescriptor *other) const
884{
885 Q_UNUSED(other);
886 return true;
887}
888
890{
891 QNullRenderPassDescriptor *rpD = new QNullRenderPassDescriptor(m_rhi);
892 QRHI_RES_RHI(QRhiNull);
893 rhiD->registerResource(rpD, false);
894 return rpD;
895}
896
901
902QNullSwapChainRenderTarget::QNullSwapChainRenderTarget(QRhiImplementation *rhi, QRhiSwapChain *swapchain)
904 d(rhi)
905{
906}
907
912
916
918{
919 return d.pixelSize;
920}
921
923{
924 return d.dpr;
925}
926
928{
929 return 1;
930}
931
933 const QRhiTextureRenderTargetDescription &desc,
934 Flags flags)
936 d(rhi)
937{
938}
939
944
946{
947 QRHI_RES_RHI(QRhiNull);
948 if (rhiD)
949 rhiD->unregisterResource(this);
950}
951
953{
954 QNullRenderPassDescriptor *rpD = new QNullRenderPassDescriptor(m_rhi);
955 QRHI_RES_RHI(QRhiNull);
956 rhiD->registerResource(rpD, false);
957 return rpD;
958}
959
961{
962 QRHI_RES_RHI(QRhiNull);
963 d.rp = QRHI_RES(QNullRenderPassDescriptor, m_renderPassDesc);
964 if (m_desc.cbeginColorAttachments() != m_desc.cendColorAttachments()) {
965 const QRhiColorAttachment *colorAtt = m_desc.cbeginColorAttachments();
966 QRhiTexture *tex = colorAtt->texture();
967 QRhiRenderBuffer *rb = colorAtt->renderBuffer();
968 d.pixelSize = tex ? rhiD->q->sizeForMipLevel(colorAtt->level(), tex->pixelSize()) : rb->pixelSize();
969 } else if (m_desc.depthStencilBuffer()) {
970 d.pixelSize = m_desc.depthStencilBuffer()->pixelSize();
971 } else if (m_desc.depthTexture()) {
972 d.pixelSize = m_desc.depthTexture()->pixelSize();
973 }
974 QRhiRenderTargetAttachmentTracker::updateResIdList<QNullTexture, QNullRenderBuffer>(m_desc, &d.currentResIdList);
975 rhiD->registerResource(this);
976 return true;
977}
978
980{
981 if (!QRhiRenderTargetAttachmentTracker::isUpToDate<QNullTexture, QNullRenderBuffer>(m_desc, d.currentResIdList))
982 const_cast<QNullTextureRenderTarget *>(this)->create();
983
984 return d.pixelSize;
985}
986
988{
989 return d.dpr;
990}
991
993{
994 return 1;
995}
996
1001
1006
1008{
1009 QRHI_RES_RHI(QRhiNull);
1010 if (rhiD)
1011 rhiD->unregisterResource(this);
1012}
1013
1015{
1016 QRHI_RES_RHI(QRhiNull);
1017 if (!rhiD->sanityCheckShaderResourceBindings(this))
1018 return false;
1019
1020 rhiD->updateLayoutDesc(this);
1021
1022 rhiD->registerResource(this, false);
1023 return true;
1024}
1025
1027{
1028 Q_UNUSED(flags);
1029}
1030
1033{
1034}
1035
1040
1042{
1043 QRHI_RES_RHI(QRhiNull);
1044 if (rhiD)
1045 rhiD->unregisterResource(this);
1046}
1047
1049{
1050 QRHI_RES_RHI(QRhiNull);
1051 if (!rhiD->sanityCheckGraphicsPipeline(this))
1052 return false;
1053
1054 rhiD->registerResource(this);
1055 return true;
1056}
1057
1060{
1061}
1062
1067
1069{
1070 QRHI_RES_RHI(QRhiNull);
1071 if (rhiD)
1072 rhiD->unregisterResource(this);
1073}
1074
1076{
1077 QRHI_RES_RHI(QRhiNull);
1078 rhiD->registerResource(this);
1079 return true;
1080}
1081
1084{
1085}
1086
1091
1093{
1094 // nothing to do here
1095}
1096
1097QNullSwapChain::QNullSwapChain(QRhiImplementation *rhi)
1098 : QRhiSwapChain(rhi),
1099 rt(rhi, this),
1100 cb(rhi)
1101{
1102}
1103
1108
1110{
1111 QRHI_RES_RHI(QRhiNull);
1112 if (rhiD)
1113 rhiD->unregisterResource(this);
1114}
1115
1117{
1118 return &cb;
1119}
1120
1125
1127{
1128 return QSize(1280, 720);
1129}
1130
1132{
1133 return f == SDR;
1134}
1135
1137{
1138 QNullRenderPassDescriptor *rpD = new QNullRenderPassDescriptor(m_rhi);
1139 QRHI_RES_RHI(QRhiNull);
1140 rhiD->registerResource(rpD, false);
1141 return rpD;
1142}
1143
1145{
1146 const bool needsRegistration = !window || window != m_window;
1147 if (window && window != m_window)
1148 destroy();
1149
1150 window = m_window;
1151 m_currentPixelSize = surfacePixelSize();
1152 rt.setRenderPassDescriptor(m_renderPassDesc); // for the public getter in QRhiRenderTarget
1153 rt.d.rp = QRHI_RES(QNullRenderPassDescriptor, m_renderPassDesc);
1154 rt.d.pixelSize = m_currentPixelSize;
1155 frameCount = 0;
1156
1157 if (needsRegistration) {
1158 QRHI_RES_RHI(QRhiNull);
1159 rhiD->registerResource(this);
1160 }
1161
1162 return true;
1163}
1164
1165QT_END_NAMESPACE
const char * constData() const
Definition qrhi_p.h:477
void setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBindings *srb, int dynamicOffsetCount, const QRhiCommandBuffer::DynamicOffset *dynamicOffsets) override
Definition qrhinull.cpp:264
double lastCompletedGpuTime(QRhiCommandBuffer *cb) override
Definition qrhinull.cpp:449
QRhi::FrameOpResult endOffscreenFrame(QRhi::EndFrameFlags flags) override
Definition qrhinull.cpp:478
void setPushConstants(QRhiCommandBuffer *cb, quint32 offset, quint32 size, const void *data) override
Definition qrhinull.cpp:311
void dispatchIndirect(QRhiCommandBuffer *cb, QRhiBuffer *indirectBuffer, quint32 indirectBufferOffset) override
Definition qrhinull.cpp:425
bool isFeatureSupported(QRhi::Feature feature) const override
Definition qrhinull.cpp:114
void debugMarkMsg(QRhiCommandBuffer *cb, const QByteArray &msg) override
Definition qrhinull.cpp:405
void dispatch(QRhiCommandBuffer *cb, int x, int y, int z) override
Definition qrhinull.cpp:417
QRhi::FrameOpResult beginFrame(QRhiSwapChain *swapChain, QRhi::BeginFrameFlags flags) override
Definition qrhinull.cpp:455
void resourceUpdate(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override
Definition qrhinull.cpp:563
void drawIndexed(QRhiCommandBuffer *cb, quint32 indexCount, quint32 instanceCount, quint32 firstIndex, qint32 vertexOffset, quint32 firstInstance) override
Definition qrhinull.cpp:335
void beginComputePass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates, QRhiCommandBuffer::BeginPassFlags flags) override
Definition qrhinull.cpp:666
void beginPass(QRhiCommandBuffer *cb, QRhiRenderTarget *rt, const QColor &colorClearValue, const QRhiDepthStencilClearValue &depthStencilClearValue, QRhiResourceUpdateBatch *resourceUpdates, QRhiCommandBuffer::BeginPassFlags flags) override
Definition qrhinull.cpp:639
bool isClipDepthZeroToOne() const override
Definition qrhinull.cpp:97
void endComputePass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override
Definition qrhinull.cpp:675
void endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override
Definition qrhinull.cpp:660
QRhi::FrameOpResult endFrame(QRhiSwapChain *swapChain, QRhi::EndFrameFlags flags) override
Definition qrhinull.cpp:462
QRhi::FrameOpResult beginOffscreenFrame(QRhiCommandBuffer **cb, QRhi::BeginFrameFlags flags) override
Definition qrhinull.cpp:471
bool isYUpInNDC() const override
Definition qrhinull.cpp:92
QRhiDriverInfo driverInfo() const override
Definition qrhinull.cpp:168
void setScissor(QRhiCommandBuffer *cb, const QRhiScissor &scissor) override
Definition qrhinull.cpp:293
void simulateTextureUpload(const QRhiResourceUpdateBatchPrivate::TextureOp &u)
Definition qrhinull.cpp:489
QRhiComputePipeline * createComputePipeline() override
Definition qrhinull.cpp:248
void setPipelineCacheData(const QByteArray &data) override
Definition qrhinull.cpp:206
void setVertexInput(QRhiCommandBuffer *cb, int startBinding, int bindingCount, const QRhiCommandBuffer::VertexInput *bindings, QRhiBuffer *indexBuf, quint32 indexOffset, QRhiCommandBuffer::IndexFormat indexFormat) override
Definition qrhinull.cpp:274
void debugMarkBegin(QRhiCommandBuffer *cb, const QByteArray &name) override
Definition qrhinull.cpp:394
void draw(QRhiCommandBuffer *cb, quint32 vertexCount, quint32 instanceCount, quint32 firstVertex, quint32 firstInstance) override
Definition qrhinull.cpp:325
QByteArray pipelineCacheData() override
Definition qrhinull.cpp:201
void drawIndirectCount(QRhiCommandBuffer *cb, QRhiBuffer *indirectBuffer, quint32 indirectBufferOffset, QRhiBuffer *countBuffer, quint32 countBufferOffset, quint32 maxDrawCount, quint32 stride) override
Definition qrhinull.cpp:366
void drawIndexedIndirectCount(QRhiCommandBuffer *cb, QRhiBuffer *indirectBuffer, quint32 indirectBufferOffset, QRhiBuffer *countBuffer, quint32 countBufferOffset, quint32 maxDrawCount, quint32 stride) override
Definition qrhinull.cpp:380
void destroy() override
Definition qrhinull.cpp:57
const QRhiNativeHandles * nativeHandles() override
Definition qrhinull.cpp:163
void setGraphicsPipeline(QRhiCommandBuffer *cb, QRhiGraphicsPipeline *ps) override
Definition qrhinull.cpp:258
void releaseCachedResources() override
Definition qrhinull.cpp:191
void simulateTextureCopy(const QRhiResourceUpdateBatchPrivate::TextureOp &u)
Definition qrhinull.cpp:539
QRhiTexture * createTexture(QRhiTexture::Format format, const QSize &pixelSize, int depth, int arraySize, int sampleCount, QRhiTexture::Flags flags) override
Definition qrhinull.cpp:218
QList< QSize > supportedShadingRates(int sampleCount) const override
Definition qrhinull.cpp:66
void simulateTextureGenMips(const QRhiResourceUpdateBatchPrivate::TextureOp &u)
Definition qrhinull.cpp:554
void setShadingRate(QRhiCommandBuffer *cb, const QSize &coarsePixelSize) override
Definition qrhinull.cpp:319
bool makeThreadLocalNativeContextCurrent() override
Definition qrhinull.cpp:180
void drawIndirect(QRhiCommandBuffer *cb, QRhiBuffer *indirectBuffer, quint32 indirectBufferOffset, quint32 drawCount, quint32 stride) override
Definition qrhinull.cpp:346
const QRhiNativeHandles * nativeHandles(QRhiCommandBuffer *cb) override
Definition qrhinull.cpp:433
bool isYUpInFramebuffer() const override
Definition qrhinull.cpp:87
QRhi::FrameOpResult finish() override
Definition qrhinull.cpp:484
void setComputePipeline(QRhiCommandBuffer *cb, QRhiComputePipeline *ps) override
Definition qrhinull.cpp:411
QRhiStats statistics() override
Definition qrhinull.cpp:175
QRhiShadingRateMap * createShadingRateMap() override
Definition qrhinull.cpp:238
void beginExternal(QRhiCommandBuffer *cb) override
Definition qrhinull.cpp:439
QRhiSwapChain * createSwapChain() override
Definition qrhinull.cpp:72
void setViewport(QRhiCommandBuffer *cb, const QRhiViewport &viewport) override
Definition qrhinull.cpp:287
QRhiTextureRenderTarget * createTextureRenderTarget(const QRhiTextureRenderTargetDescription &desc, QRhiTextureRenderTarget::Flags flags) override
Definition qrhinull.cpp:232
QRhiGraphicsPipeline * createGraphicsPipeline() override
Definition qrhinull.cpp:243
bool create(QRhi::Flags flags) override
Definition qrhinull.cpp:51
void setStencilRef(QRhiCommandBuffer *cb, quint32 refValue) override
Definition qrhinull.cpp:305
void debugMarkEnd(QRhiCommandBuffer *cb) override
Definition qrhinull.cpp:400
QList< int > supportedSampleCounts() const override
Definition qrhinull.cpp:61
QMatrix4x4 clipSpaceCorrMatrix() const override
Definition qrhinull.cpp:102
QRhiSampler * createSampler(QRhiSampler::Filter magFilter, QRhiSampler::Filter minFilter, QRhiSampler::Filter mipmapMode, QRhiSampler::AddressMode u, QRhiSampler::AddressMode v, QRhiSampler::AddressMode w) override
Definition qrhinull.cpp:225
void drawIndexedIndirect(QRhiCommandBuffer *cb, QRhiBuffer *indirectBuffer, quint32 indirectBufferOffset, quint32 drawCount, quint32 stride) override
Definition qrhinull.cpp:356
QRhiSwapChain * currentSwapChain
Definition qrhinull_p.h:312
int ubufAlignment() const override
Definition qrhinull.cpp:82
bool isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture::Flags flags) const override
Definition qrhinull.cpp:107
int resourceLimit(QRhi::ResourceLimit limit) const override
Definition qrhinull.cpp:120
QRhiShaderResourceBindings * createShaderResourceBindings() override
Definition qrhinull.cpp:253
void setBlendConstants(QRhiCommandBuffer *cb, const QColor &c) override
Definition qrhinull.cpp:299
void endExternal(QRhiCommandBuffer *cb) override
Definition qrhinull.cpp:444
bool isDeviceLost() const override
Definition qrhinull.cpp:196
static QRhiResourceUpdateBatchPrivate * get(QRhiResourceUpdateBatch *b)
Definition qrhi_p.h:745
Combined button and popup list for selecting options.
#define QRHI_RES_RHI(t)
Definition qrhi_p.h:33
#define QRHI_RES(t, x)
Definition qrhi_p.h:32
char * data
Definition qrhinull_p.h:31
QNullBuffer(QRhiImplementation *rhi, Type type, UsageFlags usage, quint32 size)
Definition qrhinull.cpp:681
bool create() override
Creates the corresponding native graphics resources.
Definition qrhinull.cpp:701
void destroy() override
Releases (or requests deferred releasing of) the underlying native graphics resources.
Definition qrhinull.cpp:691
char * beginFullDynamicBufferUpdateForCurrentFrame() override
Definition qrhinull.cpp:715
QNullCommandBuffer(QRhiImplementation *rhi)
void destroy() override
Releases (or requests deferred releasing of) the underlying native graphics resources.
void destroy() override
Releases (or requests deferred releasing of) the underlying native graphics resources.
bool create() override
QNullComputePipeline(QRhiImplementation *rhi)
void destroy() override
Releases (or requests deferred releasing of) the underlying native graphics resources.
bool create() override
Creates the corresponding native graphics resources.
QNullGraphicsPipeline(QRhiImplementation *rhi)
void destroy() override
Releases (or requests deferred releasing of) the underlying native graphics resources.
Definition qrhinull.cpp:733
bool create() override
Creates the corresponding native graphics resources.
Definition qrhinull.cpp:742
QNullRenderBuffer(QRhiImplementation *rhi, Type type, const QSize &pixelSize, int sampleCount, QRhiRenderBuffer::Flags flags, QRhiTexture::Format backingFormatHint)
Definition qrhinull.cpp:721
QRhiTexture::Format backingFormat() const override
Definition qrhinull.cpp:756
QNullRenderPassDescriptor(QRhiImplementation *rhi)
Definition qrhinull.cpp:866
QRhiRenderPassDescriptor * newCompatibleRenderPassDescriptor() const override
Definition qrhinull.cpp:889
QVector< quint32 > serializedFormat() const override
Definition qrhinull.cpp:897
void destroy() override
Releases (or requests deferred releasing of) the underlying native graphics resources.
Definition qrhinull.cpp:876
bool isCompatible(const QRhiRenderPassDescriptor *other) const override
Definition qrhinull.cpp:883
void destroy() override
Releases (or requests deferred releasing of) the underlying native graphics resources.
Definition qrhinull.cpp:852
QNullSampler(QRhiImplementation *rhi, Filter magFilter, Filter minFilter, Filter mipmapMode, AddressMode u, AddressMode v, AddressMode w)
Definition qrhinull.cpp:841
bool create() override
Definition qrhinull.cpp:859
QNullShaderResourceBindings(QRhiImplementation *rhi)
Definition qrhinull.cpp:997
bool create() override
Creates the corresponding resource binding set.
void updateResources(UpdateFlags flags) override
void destroy() override
Releases (or requests deferred releasing of) the underlying native graphics resources.
QSize pixelSize() const override
Definition qrhinull.cpp:917
float devicePixelRatio() const override
Definition qrhinull.cpp:922
QNullSwapChainRenderTarget(QRhiImplementation *rhi, QRhiSwapChain *swapchain)
Definition qrhinull.cpp:902
int sampleCount() const override
Definition qrhinull.cpp:927
void destroy() override
Releases (or requests deferred releasing of) the underlying native graphics resources.
Definition qrhinull.cpp:913
bool createOrResize() override
Creates the swapchain if not already done and resizes the swapchain buffers to match the current size...
QSize surfacePixelSize() override
bool isFormatSupported(Format f) override
void destroy() override
Releases (or requests deferred releasing of) the underlying native graphics resources.
QRhiCommandBuffer * currentFrameCommandBuffer() override
QRhiRenderPassDescriptor * newCompatibleRenderPassDescriptor() override
QRhiRenderTarget * currentFrameRenderTarget() override
QNullSwapChain(QRhiImplementation *rhi)
QSize pixelSize() const override
Definition qrhinull.cpp:979
int sampleCount() const override
Definition qrhinull.cpp:992
void destroy() override
Releases (or requests deferred releasing of) the underlying native graphics resources.
Definition qrhinull.cpp:945
QRhiRenderPassDescriptor * newCompatibleRenderPassDescriptor() override
Definition qrhinull.cpp:952
bool create() override
Creates the corresponding native graphics resources.
Definition qrhinull.cpp:960
QNullTextureRenderTarget(QRhiImplementation *rhi, const QRhiTextureRenderTargetDescription &desc, Flags flags)
Definition qrhinull.cpp:932
float devicePixelRatio() const override
Definition qrhinull.cpp:987
bool create() override
Creates the corresponding native graphics resources.
Definition qrhinull.cpp:781
bool createFrom(NativeTexture src) override
Similar to create(), except that no new native textures are created.
Definition qrhinull.cpp:825
QNullTexture(QRhiImplementation *rhi, Format format, const QSize &pixelSize, int depth, int arraySize, int sampleCount, Flags flags)
Definition qrhinull.cpp:761
uint generation
Definition qrhinull_p.h:59
void destroy() override
Releases (or requests deferred releasing of) the underlying native graphics resources.
Definition qrhinull.cpp:772
\inmodule QtGuiPrivate \inheaderfile rhi/qrhi.h
Definition qrhi.h:1965