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::MaxVertexStorageBuffers:
152 case QRhi::MaxFragmentStorageBuffers:
153 return 32;
154 case QRhi::ShadingRateImageTileSize:
155 return 0;
156 }
157
158 Q_UNREACHABLE_RETURN(0);
159}
160
162{
163 return &nativeHandlesStruct;
164}
165
167{
168 QRhiDriverInfo info;
169 info.deviceName = QByteArrayLiteral("Null");
170 return info;
171}
172
174{
175 return {};
176}
177
179{
180 // not applicable
181 return false;
182}
183
184void QRhiNull::setQueueSubmitParams(QRhiNativeHandles *)
185{
186 // not applicable
187}
188
190{
191 // nothing to do here
192}
193
195{
196 return false;
197}
198
200{
201 return QByteArray();
202}
203
204void QRhiNull::setPipelineCacheData(const QByteArray &data)
205{
206 Q_UNUSED(data);
207}
208
209QRhiRenderBuffer *QRhiNull::createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize,
210 int sampleCount, QRhiRenderBuffer::Flags flags,
211 QRhiTexture::Format backingFormatHint)
212{
213 return new QNullRenderBuffer(this, type, pixelSize, sampleCount, flags, backingFormatHint);
214}
215
216QRhiTexture *QRhiNull::createTexture(QRhiTexture::Format format,
217 const QSize &pixelSize, int depth, int arraySize,
218 int sampleCount, QRhiTexture::Flags flags)
219{
220 return new QNullTexture(this, format, pixelSize, depth, arraySize, sampleCount, flags);
221}
222
223QRhiSampler *QRhiNull::createSampler(QRhiSampler::Filter magFilter, QRhiSampler::Filter minFilter,
224 QRhiSampler::Filter mipmapMode,
225 QRhiSampler::AddressMode u, QRhiSampler::AddressMode v, QRhiSampler::AddressMode w)
226{
227 return new QNullSampler(this, magFilter, minFilter, mipmapMode, u, v, w);
228}
229
230QRhiTextureRenderTarget *QRhiNull::createTextureRenderTarget(const QRhiTextureRenderTargetDescription &desc,
231 QRhiTextureRenderTarget::Flags flags)
232{
233 return new QNullTextureRenderTarget(this, desc, flags);
234}
235
236QRhiShadingRateMap *QRhiNull::createShadingRateMap()
237{
238 return nullptr;
239}
240
242{
243 return new QNullGraphicsPipeline(this);
244}
245
247{
248 return new QNullComputePipeline(this);
249}
250
252{
253 return new QNullShaderResourceBindings(this);
254}
255
256void QRhiNull::setGraphicsPipeline(QRhiCommandBuffer *cb, QRhiGraphicsPipeline *ps)
257{
258 Q_UNUSED(cb);
259 Q_UNUSED(ps);
260}
261
262void QRhiNull::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBindings *srb,
263 int dynamicOffsetCount,
264 const QRhiCommandBuffer::DynamicOffset *dynamicOffsets)
265{
266 Q_UNUSED(cb);
267 Q_UNUSED(srb);
268 Q_UNUSED(dynamicOffsetCount);
269 Q_UNUSED(dynamicOffsets);
270}
271
272void QRhiNull::setVertexInput(QRhiCommandBuffer *cb,
273 int startBinding, int bindingCount, const QRhiCommandBuffer::VertexInput *bindings,
274 QRhiBuffer *indexBuf, quint32 indexOffset, QRhiCommandBuffer::IndexFormat indexFormat)
275{
276 Q_UNUSED(cb);
277 Q_UNUSED(startBinding);
278 Q_UNUSED(bindingCount);
279 Q_UNUSED(bindings);
280 Q_UNUSED(indexBuf);
281 Q_UNUSED(indexOffset);
282 Q_UNUSED(indexFormat);
283}
284
285void QRhiNull::setViewport(QRhiCommandBuffer *cb, const QRhiViewport &viewport)
286{
287 Q_UNUSED(cb);
288 Q_UNUSED(viewport);
289}
290
291void QRhiNull::setScissor(QRhiCommandBuffer *cb, const QRhiScissor &scissor)
292{
293 Q_UNUSED(cb);
294 Q_UNUSED(scissor);
295}
296
297void QRhiNull::setBlendConstants(QRhiCommandBuffer *cb, const QColor &c)
298{
299 Q_UNUSED(cb);
300 Q_UNUSED(c);
301}
302
303void QRhiNull::setStencilRef(QRhiCommandBuffer *cb, quint32 refValue)
304{
305 Q_UNUSED(cb);
306 Q_UNUSED(refValue);
307}
308
309void QRhiNull::setShadingRate(QRhiCommandBuffer *cb, const QSize &coarsePixelSize)
310{
311 Q_UNUSED(cb);
312 Q_UNUSED(coarsePixelSize);
313}
314
315void QRhiNull::draw(QRhiCommandBuffer *cb, quint32 vertexCount,
316 quint32 instanceCount, quint32 firstVertex, quint32 firstInstance)
317{
318 Q_UNUSED(cb);
319 Q_UNUSED(vertexCount);
320 Q_UNUSED(instanceCount);
321 Q_UNUSED(firstVertex);
322 Q_UNUSED(firstInstance);
323}
324
325void QRhiNull::drawIndexed(QRhiCommandBuffer *cb, quint32 indexCount,
326 quint32 instanceCount, quint32 firstIndex, qint32 vertexOffset, quint32 firstInstance)
327{
328 Q_UNUSED(cb);
329 Q_UNUSED(indexCount);
330 Q_UNUSED(instanceCount);
331 Q_UNUSED(firstIndex);
332 Q_UNUSED(vertexOffset);
333 Q_UNUSED(firstInstance);
334}
335
336void QRhiNull::drawIndirect(QRhiCommandBuffer *cb, QRhiBuffer *indirectBuffer,
337 quint32 indirectBufferOffset, quint32 drawCount, quint32 stride)
338{
339 Q_UNUSED(cb);
340 Q_UNUSED(indirectBuffer);
341 Q_UNUSED(indirectBufferOffset);
342 Q_UNUSED(drawCount);
343 Q_UNUSED(stride);
344}
345
346void QRhiNull::drawIndexedIndirect(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::drawIndirectCount(QRhiCommandBuffer *cb,
357 QRhiBuffer *indirectBuffer, quint32 indirectBufferOffset,
358 QRhiBuffer *countBuffer, quint32 countBufferOffset,
359 quint32 maxDrawCount, quint32 stride)
360{
361 Q_UNUSED(cb);
362 Q_UNUSED(indirectBuffer);
363 Q_UNUSED(indirectBufferOffset);
364 Q_UNUSED(countBuffer);
365 Q_UNUSED(countBufferOffset);
366 Q_UNUSED(maxDrawCount);
367 Q_UNUSED(stride);
368}
369
370void QRhiNull::drawIndexedIndirectCount(QRhiCommandBuffer *cb,
371 QRhiBuffer *indirectBuffer, quint32 indirectBufferOffset,
372 QRhiBuffer *countBuffer, quint32 countBufferOffset,
373 quint32 maxDrawCount, quint32 stride)
374{
375 Q_UNUSED(cb);
376 Q_UNUSED(indirectBuffer);
377 Q_UNUSED(indirectBufferOffset);
378 Q_UNUSED(countBuffer);
379 Q_UNUSED(countBufferOffset);
380 Q_UNUSED(maxDrawCount);
381 Q_UNUSED(stride);
382}
383
384void QRhiNull::debugMarkBegin(QRhiCommandBuffer *cb, const QByteArray &name)
385{
386 Q_UNUSED(cb);
387 Q_UNUSED(name);
388}
389
390void QRhiNull::debugMarkEnd(QRhiCommandBuffer *cb)
391{
392 Q_UNUSED(cb);
393}
394
395void QRhiNull::debugMarkMsg(QRhiCommandBuffer *cb, const QByteArray &msg)
396{
397 Q_UNUSED(cb);
398 Q_UNUSED(msg);
399}
400
401void QRhiNull::setComputePipeline(QRhiCommandBuffer *cb, QRhiComputePipeline *ps)
402{
403 Q_UNUSED(cb);
404 Q_UNUSED(ps);
405}
406
407void QRhiNull::dispatch(QRhiCommandBuffer *cb, int x, int y, int z)
408{
409 Q_UNUSED(cb);
410 Q_UNUSED(x);
411 Q_UNUSED(y);
412 Q_UNUSED(z);
413}
414
415void QRhiNull::dispatchIndirect(QRhiCommandBuffer *cb, QRhiBuffer *indirectBuffer,
416 quint32 indirectBufferOffset)
417{
418 Q_UNUSED(cb);
419 Q_UNUSED(indirectBuffer);
420 Q_UNUSED(indirectBufferOffset);
421}
422
423const QRhiNativeHandles *QRhiNull::nativeHandles(QRhiCommandBuffer *cb)
424{
425 Q_UNUSED(cb);
426 return nullptr;
427}
428
429void QRhiNull::beginExternal(QRhiCommandBuffer *cb)
430{
431 Q_UNUSED(cb);
432}
433
434void QRhiNull::endExternal(QRhiCommandBuffer *cb)
435{
436 Q_UNUSED(cb);
437}
438
439double QRhiNull::lastCompletedGpuTime(QRhiCommandBuffer *cb)
440{
441 Q_UNUSED(cb);
442 return 0;
443}
444
445QRhi::FrameOpResult QRhiNull::beginFrame(QRhiSwapChain *swapChain, QRhi::BeginFrameFlags flags)
446{
447 Q_UNUSED(flags);
448 currentSwapChain = swapChain;
449 return QRhi::FrameOpSuccess;
450}
451
452QRhi::FrameOpResult QRhiNull::endFrame(QRhiSwapChain *swapChain, QRhi::EndFrameFlags flags)
453{
454 Q_UNUSED(flags);
455 QNullSwapChain *swapChainD = QRHI_RES(QNullSwapChain, swapChain);
456 swapChainD->frameCount += 1;
457 currentSwapChain = nullptr;
458 return QRhi::FrameOpSuccess;
459}
460
461QRhi::FrameOpResult QRhiNull::beginOffscreenFrame(QRhiCommandBuffer **cb, QRhi::BeginFrameFlags flags)
462{
463 Q_UNUSED(flags);
464 *cb = &offscreenCommandBuffer;
465 return QRhi::FrameOpSuccess;
466}
467
468QRhi::FrameOpResult QRhiNull::endOffscreenFrame(QRhi::EndFrameFlags flags)
469{
470 Q_UNUSED(flags);
471 return QRhi::FrameOpSuccess;
472}
473
475{
476 return QRhi::FrameOpSuccess;
477}
478
480{
481 QNullTexture *texD = QRHI_RES(QNullTexture, u.dst);
482 for (int layer = 0, maxLayer = u.subresDesc.size(); layer < maxLayer; ++layer) {
483 for (int level = 0; level < QRhi::MAX_MIP_LEVELS; ++level) {
484 for (const QRhiTextureSubresourceUploadDescription &subresDesc : std::as_const(u.subresDesc[layer][level])) {
485 if (!subresDesc.image().isNull()) {
486 const QImage src = subresDesc.image();
487 QPainter painter(&texD->image[layer][level]);
488 const QSize srcSize = subresDesc.sourceSize().isEmpty()
489 ? src.size() : subresDesc.sourceSize();
490 painter.setCompositionMode(QPainter::CompositionMode_Source);
491 painter.drawImage(subresDesc.destinationTopLeft(), src,
492 QRect(subresDesc.sourceTopLeft(), srcSize));
493 } else if (!subresDesc.data().isEmpty()) {
494 const QSize subresSize = q->sizeForMipLevel(level, texD->pixelSize());
495 int w = subresSize.width();
496 int h = subresSize.height();
497 if (!subresDesc.sourceSize().isEmpty()) {
498 w = subresDesc.sourceSize().width();
499 h = subresDesc.sourceSize().height();
500 }
501 // sourceTopLeft is not supported on this path as per QRhi docs
502 const QByteArray srcData = subresDesc.data();
503 const QPoint dstOffset = subresDesc.destinationTopLeft();
504 QSize size = clampedSubResourceUploadSize(QSize(w, h), dstOffset, level,
505 texD->pixelSize());
506 size = clampedSubResourceUploadSizeForSourceData(size, subresDesc.dataStride(),
507 4, srcData.size());
508 if (size.isEmpty())
509 continue;
510 w = size.width();
511 h = size.height();
512 const char *src = srcData.constData();
513 const int srcBpl = w * 4;
514 int srcStride = srcBpl;
515 if (subresDesc.dataStride())
516 srcStride = subresDesc.dataStride();
517 uchar *dst = texD->image[layer][level].bits();
518 const int dstBpl = texD->image[layer][level].bytesPerLine();
519 for (int y = 0; y < h; ++y) {
520 memcpy(dst + dstOffset.x() * 4 + (y + dstOffset.y()) * dstBpl,
521 src + y * srcStride,
522 size_t(srcBpl));
523 }
524 }
525 }
526 }
527 }
528}
529
531{
532 QNullTexture *srcD = QRHI_RES(QNullTexture, u.src);
533 QNullTexture *dstD = QRHI_RES(QNullTexture, u.dst);
534 const QImage &srcImage(srcD->image[u.desc.sourceLayer()][u.desc.sourceLevel()]);
535 QImage &dstImage(dstD->image[u.desc.destinationLayer()][u.desc.destinationLevel()]);
536 const QPoint dstPos = u.desc.destinationTopLeft();
537 const QSize size = u.desc.pixelSize().isEmpty() ? srcD->pixelSize() : u.desc.pixelSize();
538 const QPoint srcPos = u.desc.sourceTopLeft();
539
540 QPainter painter(&dstImage);
541 painter.setCompositionMode(QPainter::CompositionMode_Source);
542 painter.drawImage(QRect(dstPos, size), srcImage, QRect(srcPos, size));
543}
544
546{
547 QNullTexture *texD = QRHI_RES(QNullTexture, u.dst);
548 const QSize baseSize = texD->pixelSize();
549 const int levelCount = q->mipLevelsForSize(baseSize);
550 for (int level = 1; level < levelCount; ++level)
551 texD->image[0][level] = texD->image[0][0].scaled(q->sizeForMipLevel(level, baseSize));
552}
553
554void QRhiNull::resourceUpdate(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates)
555{
556 Q_UNUSED(cb);
558 for (int opIdx = 0; opIdx < ud->activeBufferOpCount; ++opIdx) {
559 const QRhiResourceUpdateBatchPrivate::BufferOp &u(ud->bufferOps[opIdx]);
562 {
563 QNullBuffer *bufD = QRHI_RES(QNullBuffer, u.buf);
564 memcpy(bufD->data + u.offset, u.data.constData(), size_t(u.data.size()));
566 QRhiReadbackResult *result = u.result;
567 result->data.resize(u.readSize);
568 QNullBuffer *bufD = QRHI_RES(QNullBuffer, u.buf);
569 memcpy(result->data.data(), bufD->data + u.offset, size_t(u.readSize));
570 if (result->completed)
571 result->completed();
572 }
573 }
574 for (int opIdx = 0; opIdx < ud->activeTextureOpCount; ++opIdx) {
575 const QRhiResourceUpdateBatchPrivate::TextureOp &u(ud->textureOps[opIdx]);
577 if (u.dst->format() == QRhiTexture::RGBA8)
580 if (u.src->format() == QRhiTexture::RGBA8 && u.dst->format() == QRhiTexture::RGBA8)
583 QRhiReadbackResult *result = u.result;
584 QNullTexture *texD = QRHI_RES(QNullTexture, u.rb.texture());
585 if (texD) {
586 result->format = texD->format();
587 if (u.rb.rect().isValid())
588 result->pixelSize = u.rb.rect().size();
589 else
590 result->pixelSize = q->sizeForMipLevel(u.rb.level(), texD->pixelSize());
591 } else {
592 Q_ASSERT(currentSwapChain);
593 result->format = QRhiTexture::RGBA8;
594 if (u.rb.rect().isValid())
595 result->pixelSize = u.rb.rect().size();
596 else
597 result->pixelSize = currentSwapChain->currentPixelSize();
598 }
599 quint32 bytesPerLine = 0;
600 quint32 byteSize = 0;
601 textureFormatInfo(result->format, result->pixelSize, &bytesPerLine, &byteSize, nullptr);
602 if (texD && texD->format() == QRhiTexture::RGBA8) {
603 result->data.resize(int(byteSize));
604 const QImage &src(texD->image[u.rb.layer()][u.rb.level()]);
605 char *dst = result->data.data();
606 for (int y = 0, h = src.height(); y < h; ++y) {
607 memcpy(dst, src.constScanLine(y), bytesPerLine);
608 dst += bytesPerLine;
609 }
610 } else {
611 result->data.fill(0, int(byteSize));
612 }
613 if (result->completed)
614 result->completed();
616 if (u.dst->format() == QRhiTexture::RGBA8)
618 }
619 }
620 ud->free();
621}
622
623void QRhiNull::beginPass(QRhiCommandBuffer *cb,
624 QRhiRenderTarget *rt,
625 const QColor &colorClearValue,
626 const QRhiDepthStencilClearValue &depthStencilClearValue,
627 QRhiResourceUpdateBatch *resourceUpdates,
628 QRhiCommandBuffer::BeginPassFlags flags)
629{
630 Q_UNUSED(colorClearValue);
631 Q_UNUSED(depthStencilClearValue);
632 Q_UNUSED(flags);
633
634 if (resourceUpdates)
635 resourceUpdate(cb, resourceUpdates);
636
637 if (rt->resourceType() == QRhiRenderTarget::TextureRenderTarget) {
639 if (!QRhiRenderTargetAttachmentTracker::isUpToDate<QNullTexture, QNullRenderBuffer>(rtTex->description(), rtTex->d.currentResIdList))
640 rtTex->create();
641 }
642}
643
644void QRhiNull::endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates)
645{
646 if (resourceUpdates)
647 resourceUpdate(cb, resourceUpdates);
648}
649
650void QRhiNull::beginComputePass(QRhiCommandBuffer *cb,
651 QRhiResourceUpdateBatch *resourceUpdates,
652 QRhiCommandBuffer::BeginPassFlags flags)
653{
654 Q_UNUSED(flags);
655 if (resourceUpdates)
656 resourceUpdate(cb, resourceUpdates);
657}
658
659void QRhiNull::endComputePass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates)
660{
661 if (resourceUpdates)
662 resourceUpdate(cb, resourceUpdates);
663}
664
665QNullBuffer::QNullBuffer(QRhiImplementation *rhi, Type type, UsageFlags usage, quint32 size)
667{
668}
669
674
676{
677 delete[] data;
678 data = nullptr;
679
680 QRHI_RES_RHI(QRhiNull);
681 if (rhiD)
682 rhiD->unregisterResource(this);
683}
684
686{
687 if (data)
688 destroy();
689
690 data = new char[m_size];
691 memset(data, 0, m_size);
692
693 QRHI_RES_RHI(QRhiNull);
694 rhiD->registerResource(this);
695
696 return true;
697}
698
700{
701 Q_ASSERT(m_type == Dynamic);
702 return data;
703}
704
705QNullRenderBuffer::QNullRenderBuffer(QRhiImplementation *rhi, Type type, const QSize &pixelSize,
706 int sampleCount, QRhiRenderBuffer::Flags flags,
707 QRhiTexture::Format backingFormatHint)
709{
710}
711
716
718{
719 valid = false;
720
721 QRHI_RES_RHI(QRhiNull);
722 if (rhiD)
723 rhiD->unregisterResource(this);
724}
725
727{
728 if (valid)
729 destroy();
730
731 valid = true;
732 generation += 1;
733
734 QRHI_RES_RHI(QRhiNull);
735 rhiD->registerResource(this);
736
737 return true;
738}
739
741{
742 return m_type == Color ? QRhiTexture::RGBA8 : QRhiTexture::UnknownFormat;
743}
744
745QNullTexture::QNullTexture(QRhiImplementation *rhi, Format format, const QSize &pixelSize, int depth,
746 int arraySize, int sampleCount, Flags flags)
748{
749}
750
755
757{
758 valid = false;
759
760 QRHI_RES_RHI(QRhiNull);
761 if (rhiD)
762 rhiD->unregisterResource(this);
763}
764
766{
767 if (valid)
768 destroy();
769
770 valid = true;
771
772 QRHI_RES_RHI(QRhiNull);
773 const bool isCube = m_flags.testFlag(CubeMap);
774 const bool is3D = m_flags.testFlag(ThreeDimensional);
775 const bool isArray = m_flags.testFlag(TextureArray);
776 const bool hasMipMaps = m_flags.testFlag(MipMapped);
777 const bool is1D = m_flags.testFlags(OneDimensional);
778 QSize size = is1D ? QSize(qMax(1, m_pixelSize.width()), 1)
779 : (m_pixelSize.isEmpty() ? QSize(1, 1) : m_pixelSize);
780 const int mipLevelCount = hasMipMaps ? rhiD->q->mipLevelsForSize(size) : 1;
781 const int layerCount = is3D ? qMax(1, m_depth)
782 : (isCube ? 6
783 : (isArray ? qMax(0, m_arraySize)
784 : 1));
785
786 if (!rhiD->textureFormatInfo(m_format, size, nullptr, nullptr, nullptr)) {
787 valid = false;
788 return false;
789 }
790
791 if (m_format == RGBA8) {
792 image.resize(layerCount);
793 for (int layer = 0; layer < layerCount; ++layer) {
794 for (int level = 0; level < mipLevelCount; ++level) {
795 image[layer][level] = QImage(rhiD->q->sizeForMipLevel(level, size),
796 QImage::Format_RGBA8888_Premultiplied);
797 image[layer][level].fill(Qt::yellow);
798 }
799 }
800 }
801
802 generation += 1;
803
804 rhiD->registerResource(this);
805
806 return true;
807}
808
809bool QNullTexture::createFrom(QRhiTexture::NativeTexture src)
810{
811 Q_UNUSED(src);
812 if (valid)
813 destroy();
814
815 valid = true;
816
817 generation += 1;
818
819 QRHI_RES_RHI(QRhiNull);
820 rhiD->registerResource(this);
821
822 return true;
823}
824
825QNullSampler::QNullSampler(QRhiImplementation *rhi, Filter magFilter, Filter minFilter, Filter mipmapMode,
826 AddressMode u, AddressMode v, AddressMode w)
828{
829}
830
835
837{
838 QRHI_RES_RHI(QRhiNull);
839 if (rhiD)
840 rhiD->unregisterResource(this);
841}
842
844{
845 QRHI_RES_RHI(QRhiNull);
846 rhiD->registerResource(this);
847 return true;
848}
849
854
859
861{
862 QRHI_RES_RHI(QRhiNull);
863 if (rhiD)
864 rhiD->unregisterResource(this);
865}
866
867bool QNullRenderPassDescriptor::isCompatible(const QRhiRenderPassDescriptor *other) const
868{
869 Q_UNUSED(other);
870 return true;
871}
872
874{
875 QNullRenderPassDescriptor *rpD = new QNullRenderPassDescriptor(m_rhi);
876 QRHI_RES_RHI(QRhiNull);
877 rhiD->registerResource(rpD, false);
878 return rpD;
879}
880
885
886QNullSwapChainRenderTarget::QNullSwapChainRenderTarget(QRhiImplementation *rhi, QRhiSwapChain *swapchain)
888 d(rhi)
889{
890}
891
896
900
902{
903 return d.pixelSize;
904}
905
907{
908 return d.dpr;
909}
910
912{
913 return 1;
914}
915
917 const QRhiTextureRenderTargetDescription &desc,
918 Flags flags)
920 d(rhi)
921{
922}
923
928
930{
931 QRHI_RES_RHI(QRhiNull);
932 if (rhiD)
933 rhiD->unregisterResource(this);
934}
935
937{
938 QNullRenderPassDescriptor *rpD = new QNullRenderPassDescriptor(m_rhi);
939 QRHI_RES_RHI(QRhiNull);
940 rhiD->registerResource(rpD, false);
941 return rpD;
942}
943
945{
946 QRHI_RES_RHI(QRhiNull);
947 d.rp = QRHI_RES(QNullRenderPassDescriptor, m_renderPassDesc);
948 if (m_desc.cbeginColorAttachments() != m_desc.cendColorAttachments()) {
949 const QRhiColorAttachment *colorAtt = m_desc.cbeginColorAttachments();
950 QRhiTexture *tex = colorAtt->texture();
951 QRhiRenderBuffer *rb = colorAtt->renderBuffer();
952 d.pixelSize = tex ? rhiD->q->sizeForMipLevel(colorAtt->level(), tex->pixelSize()) : rb->pixelSize();
953 } else if (m_desc.depthStencilBuffer()) {
954 d.pixelSize = m_desc.depthStencilBuffer()->pixelSize();
955 } else if (m_desc.depthTexture()) {
956 d.pixelSize = m_desc.depthTexture()->pixelSize();
957 }
958 QRhiRenderTargetAttachmentTracker::updateResIdList<QNullTexture, QNullRenderBuffer>(m_desc, &d.currentResIdList);
959 rhiD->registerResource(this);
960 return true;
961}
962
964{
965 if (!QRhiRenderTargetAttachmentTracker::isUpToDate<QNullTexture, QNullRenderBuffer>(m_desc, d.currentResIdList))
966 const_cast<QNullTextureRenderTarget *>(this)->create();
967
968 return d.pixelSize;
969}
970
972{
973 return d.dpr;
974}
975
977{
978 return 1;
979}
980
985
990
992{
993 QRHI_RES_RHI(QRhiNull);
994 if (rhiD)
995 rhiD->unregisterResource(this);
996}
997
999{
1000 QRHI_RES_RHI(QRhiNull);
1001 if (!rhiD->sanityCheckShaderResourceBindings(this))
1002 return false;
1003
1004 rhiD->updateLayoutDesc(this);
1005
1006 rhiD->registerResource(this, false);
1007 return true;
1008}
1009
1011{
1012 Q_UNUSED(flags);
1013}
1014
1017{
1018}
1019
1024
1026{
1027 QRHI_RES_RHI(QRhiNull);
1028 if (rhiD)
1029 rhiD->unregisterResource(this);
1030}
1031
1033{
1034 QRHI_RES_RHI(QRhiNull);
1035 if (!rhiD->sanityCheckGraphicsPipeline(this))
1036 return false;
1037
1038 rhiD->registerResource(this);
1039 return true;
1040}
1041
1044{
1045}
1046
1051
1053{
1054 QRHI_RES_RHI(QRhiNull);
1055 if (rhiD)
1056 rhiD->unregisterResource(this);
1057}
1058
1060{
1061 QRHI_RES_RHI(QRhiNull);
1062 rhiD->registerResource(this);
1063 return true;
1064}
1065
1068{
1069}
1070
1075
1077{
1078 // nothing to do here
1079}
1080
1081QNullSwapChain::QNullSwapChain(QRhiImplementation *rhi)
1082 : QRhiSwapChain(rhi),
1083 rt(rhi, this),
1084 cb(rhi)
1085{
1086}
1087
1092
1094{
1095 QRHI_RES_RHI(QRhiNull);
1096 if (rhiD)
1097 rhiD->unregisterResource(this);
1098}
1099
1101{
1102 return &cb;
1103}
1104
1109
1111{
1112 return QSize(1280, 720);
1113}
1114
1116{
1117 return f == SDR;
1118}
1119
1121{
1122 QNullRenderPassDescriptor *rpD = new QNullRenderPassDescriptor(m_rhi);
1123 QRHI_RES_RHI(QRhiNull);
1124 rhiD->registerResource(rpD, false);
1125 return rpD;
1126}
1127
1129{
1130 const bool needsRegistration = !window || window != m_window;
1131 if (window && window != m_window)
1132 destroy();
1133
1134 window = m_window;
1135 m_currentPixelSize = surfacePixelSize();
1136 rt.setRenderPassDescriptor(m_renderPassDesc); // for the public getter in QRhiRenderTarget
1137 rt.d.rp = QRHI_RES(QNullRenderPassDescriptor, m_renderPassDesc);
1138 rt.d.pixelSize = m_currentPixelSize;
1139 frameCount = 0;
1140
1141 if (needsRegistration) {
1142 QRHI_RES_RHI(QRhiNull);
1143 rhiD->registerResource(this);
1144 }
1145
1146 return true;
1147}
1148
1149QT_END_NAMESPACE
const char * constData() const
Definition qrhi_p.h:414
void setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBindings *srb, int dynamicOffsetCount, const QRhiCommandBuffer::DynamicOffset *dynamicOffsets) override
Definition qrhinull.cpp:262
double lastCompletedGpuTime(QRhiCommandBuffer *cb) override
Definition qrhinull.cpp:439
QRhi::FrameOpResult endOffscreenFrame(QRhi::EndFrameFlags flags) override
Definition qrhinull.cpp:468
void dispatchIndirect(QRhiCommandBuffer *cb, QRhiBuffer *indirectBuffer, quint32 indirectBufferOffset) override
Definition qrhinull.cpp:415
bool isFeatureSupported(QRhi::Feature feature) const override
Definition qrhinull.cpp:114
void debugMarkMsg(QRhiCommandBuffer *cb, const QByteArray &msg) override
Definition qrhinull.cpp:395
void dispatch(QRhiCommandBuffer *cb, int x, int y, int z) override
Definition qrhinull.cpp:407
QRhi::FrameOpResult beginFrame(QRhiSwapChain *swapChain, QRhi::BeginFrameFlags flags) override
Definition qrhinull.cpp:445
void resourceUpdate(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override
Definition qrhinull.cpp:554
void drawIndexed(QRhiCommandBuffer *cb, quint32 indexCount, quint32 instanceCount, quint32 firstIndex, qint32 vertexOffset, quint32 firstInstance) override
Definition qrhinull.cpp:325
void beginComputePass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates, QRhiCommandBuffer::BeginPassFlags flags) override
Definition qrhinull.cpp:650
void beginPass(QRhiCommandBuffer *cb, QRhiRenderTarget *rt, const QColor &colorClearValue, const QRhiDepthStencilClearValue &depthStencilClearValue, QRhiResourceUpdateBatch *resourceUpdates, QRhiCommandBuffer::BeginPassFlags flags) override
Definition qrhinull.cpp:623
bool isClipDepthZeroToOne() const override
Definition qrhinull.cpp:97
void endComputePass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override
Definition qrhinull.cpp:659
void endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override
Definition qrhinull.cpp:644
QRhi::FrameOpResult endFrame(QRhiSwapChain *swapChain, QRhi::EndFrameFlags flags) override
Definition qrhinull.cpp:452
QRhi::FrameOpResult beginOffscreenFrame(QRhiCommandBuffer **cb, QRhi::BeginFrameFlags flags) override
Definition qrhinull.cpp:461
bool isYUpInNDC() const override
Definition qrhinull.cpp:92
QRhiDriverInfo driverInfo() const override
Definition qrhinull.cpp:166
void setScissor(QRhiCommandBuffer *cb, const QRhiScissor &scissor) override
Definition qrhinull.cpp:291
void simulateTextureUpload(const QRhiResourceUpdateBatchPrivate::TextureOp &u)
Definition qrhinull.cpp:479
QRhiComputePipeline * createComputePipeline() override
Definition qrhinull.cpp:246
void setPipelineCacheData(const QByteArray &data) override
Definition qrhinull.cpp:204
void setVertexInput(QRhiCommandBuffer *cb, int startBinding, int bindingCount, const QRhiCommandBuffer::VertexInput *bindings, QRhiBuffer *indexBuf, quint32 indexOffset, QRhiCommandBuffer::IndexFormat indexFormat) override
Definition qrhinull.cpp:272
void debugMarkBegin(QRhiCommandBuffer *cb, const QByteArray &name) override
Definition qrhinull.cpp:384
void draw(QRhiCommandBuffer *cb, quint32 vertexCount, quint32 instanceCount, quint32 firstVertex, quint32 firstInstance) override
Definition qrhinull.cpp:315
QByteArray pipelineCacheData() override
Definition qrhinull.cpp:199
void drawIndirectCount(QRhiCommandBuffer *cb, QRhiBuffer *indirectBuffer, quint32 indirectBufferOffset, QRhiBuffer *countBuffer, quint32 countBufferOffset, quint32 maxDrawCount, quint32 stride) override
Definition qrhinull.cpp:356
void drawIndexedIndirectCount(QRhiCommandBuffer *cb, QRhiBuffer *indirectBuffer, quint32 indirectBufferOffset, QRhiBuffer *countBuffer, quint32 countBufferOffset, quint32 maxDrawCount, quint32 stride) override
Definition qrhinull.cpp:370
void destroy() override
Definition qrhinull.cpp:57
const QRhiNativeHandles * nativeHandles() override
Definition qrhinull.cpp:161
void setGraphicsPipeline(QRhiCommandBuffer *cb, QRhiGraphicsPipeline *ps) override
Definition qrhinull.cpp:256
void releaseCachedResources() override
Definition qrhinull.cpp:189
void simulateTextureCopy(const QRhiResourceUpdateBatchPrivate::TextureOp &u)
Definition qrhinull.cpp:530
QRhiTexture * createTexture(QRhiTexture::Format format, const QSize &pixelSize, int depth, int arraySize, int sampleCount, QRhiTexture::Flags flags) override
Definition qrhinull.cpp:216
QList< QSize > supportedShadingRates(int sampleCount) const override
Definition qrhinull.cpp:66
void simulateTextureGenMips(const QRhiResourceUpdateBatchPrivate::TextureOp &u)
Definition qrhinull.cpp:545
void setShadingRate(QRhiCommandBuffer *cb, const QSize &coarsePixelSize) override
Definition qrhinull.cpp:309
bool makeThreadLocalNativeContextCurrent() override
Definition qrhinull.cpp:178
void drawIndirect(QRhiCommandBuffer *cb, QRhiBuffer *indirectBuffer, quint32 indirectBufferOffset, quint32 drawCount, quint32 stride) override
Definition qrhinull.cpp:336
const QRhiNativeHandles * nativeHandles(QRhiCommandBuffer *cb) override
Definition qrhinull.cpp:423
bool isYUpInFramebuffer() const override
Definition qrhinull.cpp:87
QRhi::FrameOpResult finish() override
Definition qrhinull.cpp:474
void setComputePipeline(QRhiCommandBuffer *cb, QRhiComputePipeline *ps) override
Definition qrhinull.cpp:401
QRhiStats statistics() override
Definition qrhinull.cpp:173
QRhiShadingRateMap * createShadingRateMap() override
Definition qrhinull.cpp:236
void beginExternal(QRhiCommandBuffer *cb) override
Definition qrhinull.cpp:429
QRhiSwapChain * createSwapChain() override
Definition qrhinull.cpp:72
void setViewport(QRhiCommandBuffer *cb, const QRhiViewport &viewport) override
Definition qrhinull.cpp:285
QRhiTextureRenderTarget * createTextureRenderTarget(const QRhiTextureRenderTargetDescription &desc, QRhiTextureRenderTarget::Flags flags) override
Definition qrhinull.cpp:230
QRhiGraphicsPipeline * createGraphicsPipeline() override
Definition qrhinull.cpp:241
bool create(QRhi::Flags flags) override
Definition qrhinull.cpp:51
void setStencilRef(QRhiCommandBuffer *cb, quint32 refValue) override
Definition qrhinull.cpp:303
void debugMarkEnd(QRhiCommandBuffer *cb) override
Definition qrhinull.cpp:390
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:223
void drawIndexedIndirect(QRhiCommandBuffer *cb, QRhiBuffer *indirectBuffer, quint32 indirectBufferOffset, quint32 drawCount, quint32 stride) override
Definition qrhinull.cpp:346
QRhiSwapChain * currentSwapChain
Definition qrhinull_p.h:311
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:251
void setBlendConstants(QRhiCommandBuffer *cb, const QColor &c) override
Definition qrhinull.cpp:297
void endExternal(QRhiCommandBuffer *cb) override
Definition qrhinull.cpp:434
bool isDeviceLost() const override
Definition qrhinull.cpp:194
static QRhiResourceUpdateBatchPrivate * get(QRhiResourceUpdateBatch *b)
Definition qrhi_p.h:639
Combined button and popup list for selecting options.
#define QRHI_RES_RHI(t)
Definition qrhi_p.h:31
#define QRHI_RES(t, x)
Definition qrhi_p.h:30
char * data
Definition qrhinull_p.h:31
QNullBuffer(QRhiImplementation *rhi, Type type, UsageFlags usage, quint32 size)
Definition qrhinull.cpp:665
bool create() override
Creates the corresponding native graphics resources.
Definition qrhinull.cpp:685
void destroy() override
Releases (or requests deferred releasing of) the underlying native graphics resources.
Definition qrhinull.cpp:675
char * beginFullDynamicBufferUpdateForCurrentFrame() override
Definition qrhinull.cpp:699
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:717
bool create() override
Creates the corresponding native graphics resources.
Definition qrhinull.cpp:726
QNullRenderBuffer(QRhiImplementation *rhi, Type type, const QSize &pixelSize, int sampleCount, QRhiRenderBuffer::Flags flags, QRhiTexture::Format backingFormatHint)
Definition qrhinull.cpp:705
QRhiTexture::Format backingFormat() const override
Definition qrhinull.cpp:740
QNullRenderPassDescriptor(QRhiImplementation *rhi)
Definition qrhinull.cpp:850
QRhiRenderPassDescriptor * newCompatibleRenderPassDescriptor() const override
Definition qrhinull.cpp:873
QVector< quint32 > serializedFormat() const override
Definition qrhinull.cpp:881
void destroy() override
Releases (or requests deferred releasing of) the underlying native graphics resources.
Definition qrhinull.cpp:860
bool isCompatible(const QRhiRenderPassDescriptor *other) const override
Definition qrhinull.cpp:867
void destroy() override
Releases (or requests deferred releasing of) the underlying native graphics resources.
Definition qrhinull.cpp:836
QNullSampler(QRhiImplementation *rhi, Filter magFilter, Filter minFilter, Filter mipmapMode, AddressMode u, AddressMode v, AddressMode w)
Definition qrhinull.cpp:825
bool create() override
Definition qrhinull.cpp:843
QNullShaderResourceBindings(QRhiImplementation *rhi)
Definition qrhinull.cpp:981
bool create() override
Creates the corresponding resource binding set.
Definition qrhinull.cpp:998
void updateResources(UpdateFlags flags) override
void destroy() override
Releases (or requests deferred releasing of) the underlying native graphics resources.
Definition qrhinull.cpp:991
QSize pixelSize() const override
Definition qrhinull.cpp:901
float devicePixelRatio() const override
Definition qrhinull.cpp:906
QNullSwapChainRenderTarget(QRhiImplementation *rhi, QRhiSwapChain *swapchain)
Definition qrhinull.cpp:886
int sampleCount() const override
Definition qrhinull.cpp:911
void destroy() override
Releases (or requests deferred releasing of) the underlying native graphics resources.
Definition qrhinull.cpp:897
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:963
int sampleCount() const override
Definition qrhinull.cpp:976
void destroy() override
Releases (or requests deferred releasing of) the underlying native graphics resources.
Definition qrhinull.cpp:929
QRhiRenderPassDescriptor * newCompatibleRenderPassDescriptor() override
Definition qrhinull.cpp:936
bool create() override
Creates the corresponding native graphics resources.
Definition qrhinull.cpp:944
QNullTextureRenderTarget(QRhiImplementation *rhi, const QRhiTextureRenderTargetDescription &desc, Flags flags)
Definition qrhinull.cpp:916
float devicePixelRatio() const override
Definition qrhinull.cpp:971
bool create() override
Creates the corresponding native graphics resources.
Definition qrhinull.cpp:765
bool createFrom(NativeTexture src) override
Similar to create(), except that no new native textures are created.
Definition qrhinull.cpp:809
QNullTexture(QRhiImplementation *rhi, Format format, const QSize &pixelSize, int depth, int arraySize, int sampleCount, Flags flags)
Definition qrhinull.cpp:745
void destroy() override
Releases (or requests deferred releasing of) the underlying native graphics resources.
Definition qrhinull.cpp:756
\inmodule QtGuiPrivate \inheaderfile rhi/qrhi.h
Definition qrhi.h:1939