599void NormalPass::renderPrep(QSSGRenderer &renderer, QSSGLayerRenderData &data)
601 using namespace RenderHelpers;
603 QSSG_ASSERT(!data.renderedCameras.isEmpty(),
return);
604 QSSGRenderCamera *camera = data.renderedCameras[0];
606 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
607 QRhi *rhi = rhiCtx->rhi();
609 const auto &layerPrepResult = data.layerPrepResult;
616 ps = data.getPipelineState();
620 sortedOpaqueObjects = data.getSortedOpaqueRenderableObjects(*camera);
624 QSSGShaderFeatures shaderFeatures = data.getShaderFeatures();
625 shaderFeatures.set(QSSGShaderFeatures::Feature::NormalPass,
true);
627 normalTexture = data.getRenderResult(QSSGRenderResult::Key::NormalTexture);
629 const QSize size = layerPrepResult.textureDimensions();
630 bool needsBuild =
false;
632 if (!normalTexture->texture) {
633 QRhiTexture::Format format = QRhiTexture::RGBA16F;
634 if (!rhi->isTextureFormatSupported(format)) {
635 qWarning(
"No float formats, not great");
636 format = QRhiTexture::RGBA8;
638 normalTexture->texture = rhiCtx->rhi()->newTexture(format, size, 1, QRhiTexture::RenderTarget);
640 normalTexture->texture->setName(QByteArrayLiteral(
"Normal texture"));
641 }
else if (normalTexture->texture->pixelSize() != size) {
642 normalTexture->texture->setPixelSize(size);
646 if (!normalTexture->depthStencil) {
647 normalTexture->depthStencil = rhi->newRenderBuffer(QRhiRenderBuffer::DepthStencil, size);
649 }
else if (normalTexture->depthStencil->pixelSize() != size) {
650 normalTexture->depthStencil->setPixelSize(size);
655 if (!normalTexture->texture->create()) {
656 qWarning(
"Failed to build normal texture (size %dx%d, format %d)",
657 size.width(), size.height(),
int(normalTexture->texture->format()));
658 normalTexture->reset();
662 if (!normalTexture->depthStencil->create()) {
663 qWarning(
"Failed to build depth-stencil buffer for normal texture (size %dx%d)",
664 size.width(), size.height());
665 normalTexture->reset();
669 normalTexture->resetRenderTarget();
671 QRhiTextureRenderTargetDescription rtDesc;
672 QRhiColorAttachment colorAttachment(normalTexture->texture);
673 rtDesc.setColorAttachments({ colorAttachment });
674 rtDesc.setDepthStencilBuffer(normalTexture->depthStencil);
676 normalTexture->rt = rhi->newTextureRenderTarget(rtDesc);
677 normalTexture->rt->setName(QByteArrayLiteral(
"Normal texture RT"));
678 normalTexture->rpDesc = normalTexture->rt->newCompatibleRenderPassDescriptor();
679 normalTexture->rt->setRenderPassDescriptor(normalTexture->rpDesc);
680 if (!normalTexture->rt->create()) {
681 qWarning(
"Failed to build render target for normal texture");
682 normalTexture->reset();
687 rhiPrepareNormalPass(rhiCtx.get(),
this, ps, normalTexture->rpDesc, data, sortedOpaqueObjects);
1188 const auto &ctx = *renderer.contextInterface();
1189 const auto &rhiCtx = ctx.rhiContext();
1190 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(),
return);
1191 QSSG_ASSERT(!data.renderedCameras.isEmpty(),
return);
1192 QSSG_ASSERT(data.renderedCameras.count() == data.layer.viewCount,
return);
1193 layer = &data.layer;
1198 rpDesc = rhiCtx->mainRenderPassDescriptor();
1199 ps = data.getPipelineState();
1200 ps.samples = rhiCtx->mainPassSampleCount();
1201 ps.viewCount = data.layer.viewCount;
1202 ps.polygonMode = QRhiGraphicsPipeline::Fill;
1205 skipTonemapping = layer->firstEffect !=
nullptr;
1207 QRhi *rhi = rhiCtx->rhi();
1208 QSSGRenderSkyMaterial &skyMaterial = *layer->skyMaterial;
1209 const int viewCount = data.layer.viewCount;
1211 const QSSGRenderLayer::TonemapMode tonemapMode =
1212 skipTonemapping && (layer->tonemapMode != QSSGRenderLayer::TonemapMode::Custom)
1213 ? QSSGRenderLayer::TonemapMode::None
1214 : layer->tonemapMode;
1215 QSSGShaderFeatures tonemapFeatures;
1216 quint32 tonemapKey = 0;
1217 skyMaterialTonemapFeatures(tonemapMode, tonemapFeatures, tonemapKey);
1219 pipeline = skyMaterial.ensureBackgroundPipeline(ctx, tonemapFeatures, tonemapKey, viewCount);
1227 const QMatrix3x3 o = layer->lightProbeSettings.probeOrientation;
1228 const QMatrix4x4 orientation(o(0, 0), o(0, 1), o(0, 2), 0.0f,
1229 o(1, 0), o(1, 1), o(1, 2), 0.0f,
1230 o(2, 0), o(2, 1), o(2, 2), 0.0f,
1231 0.0f, 0.0f, 0.0f, 1.0f);
1232 QVarLengthArray<QMatrix4x4, 2> inverseProjections;
1233 QVarLengthArray<QMatrix4x4, 2> viewRotations;
1234 for (
int v = 0; v < viewCount; ++v) {
1235 const QSSGRenderCamera &camera = *data.renderedCameras[v];
1236 inverseProjections.append(camera.projection.inverted());
1237 QMatrix4x4 cameraRotation = data.getGlobalTransform(camera);
1238 cameraRotation.setColumn(3, QVector4D(0.0f, 0.0f, 0.0f, 1.0f));
1239 viewRotations.append(orientation * cameraRotation);
1241 const float adjustY = rhi->isYUpInNDC() ? 1.0f : -1.0f;
1242 const float exposure = layer->lightProbeSettings.probeExposure;
1244 skyMaterial.updateBackgroundUniforms(ctx, inverseProjections, viewRotations, adjustY, exposure);
1246 QSSGRhiContextPrivate *rhiCtxD = QSSGRhiContextPrivate::get(rhiCtx.get());
1247 backgroundSrb = rhiCtxD->srb(skyMaterial.backgroundBindings);
1249 switch (skyMaterial.skyboxMode) {
1250 case QSSGRenderSkyMaterial::SkyboxMode::ScreenSpaceHalf:
1253 case QSSGRenderSkyMaterial::SkyboxMode::ScreenSpaceQuarter:
1256 case QSSGRenderSkyMaterial::SkyboxMode::ScreenSpaceFull:
1257 case QSSGRenderSkyMaterial::SkyboxMode::Cubemap:
1262 renderer.rhiQuadRenderer()->prepareQuad(rhiCtx.get(),
nullptr);
1267 const std::array<
float, 4> vp = ps.viewport.viewport();
1268 const QSize fullSize(
int(vp.at(2)),
int(vp.at(3)));
1269 const QSize targetSize = (fullSize / qreal(
scaleDivisor)).expandedTo(QSize(1, 1));
1270 const bool multiView = viewCount >= 2;
1271 const int wantArraySize = multiView ? viewCount : 0;
1273 offscreenTexture = data.getRenderResult(QSSGRenderResult::Key::SkyMaterialBackgroundTexture);
1274 QSSGRhiRenderableTexture *tex = offscreenTexture;
1275 if (!tex->texture || tex->texture->pixelSize() != targetSize || tex->texture->arraySize() != wantArraySize) {
1277 tex->texture = multiView ? rhi->newTextureArray(QRhiTexture::RGBA16F, viewCount, targetSize, 1, QRhiTexture::RenderTarget)
1278 : rhi->newTexture(QRhiTexture::RGBA16F, targetSize, 1, QRhiTexture::RenderTarget);
1279 if (!tex->texture->create()) {
1280 qWarning(
"Failed to build SkyMaterial screen-space background texture");
1282 offscreenTexture =
nullptr;
1285 QRhiColorAttachment att(tex->texture);
1286 att.setMultiViewCount(viewCount);
1287 QRhiTextureRenderTargetDescription desc;
1288 desc.setColorAttachments({ att });
1289 tex->rt = rhi->newTextureRenderTarget(desc);
1290 tex->rt->setName(QByteArrayLiteral(
"SkyMaterial screen-space background"));
1291 tex->rpDesc = tex->rt->newCompatibleRenderPassDescriptor();
1292 tex->rt->setRenderPassDescriptor(tex->rpDesc);
1293 if (!tex->rt->create()) {
1294 qWarning(
"Failed to build SkyMaterial screen-space background render target");
1296 offscreenTexture =
nullptr;
1301 QSSGRhiGraphicsPipelineState offscreenPs;
1302 offscreenPs.viewport = QRhiViewport(0, 0,
float(targetSize.width()),
float(targetSize.height()));
1303 offscreenPs.samples = 1;
1304 offscreenPs.viewCount = viewCount;
1305 offscreenPs.polygonMode = QRhiGraphicsPipeline::Fill;
1306 QSSGRhiGraphicsPipelineStatePrivate::setShaderPipeline(offscreenPs, pipeline.get());
1307 renderer.rhiQuadRenderer()->recordRenderQuadPass(rhiCtx.get(), &offscreenPs, backgroundSrb,
1308 offscreenTexture->rt, QSSGRhiQuadRenderer::RenderBehind);
1677 auto *ctx = renderer.contextInterface();
1678 const auto &rhiCtx = ctx->rhiContext();
1679 auto *rhi = rhiCtx->rhi();
1681 QSSG_ASSERT(!data.renderedCameras.isEmpty() && data.renderedCameraData.has_value() ,
return);
1682 QSSGRenderCamera *camera = data.renderedCameras[0];
1684 ps = data.getPipelineState();
1685 ps.samples = rhiCtx->mainPassSampleCount();
1686 ps.viewCount = rhiCtx->mainPassViewCount();
1688 ps.flags.setFlag(QSSGRhiGraphicsPipelineState::Flag::BlendEnabled,
true);
1689 ps.flags.setFlag(QSSGRhiGraphicsPipelineState::Flag::DepthWriteEnabled,
false);
1691 shaderFeatures = data.getShaderFeatures();
1692 sortedTransparentObjects = data.getSortedTransparentRenderableObjects(*camera);
1694 if (method == QSSGRenderLayer::OITMethod::WeightedBlended) {
1695 ps.colorAttachmentCount = 2;
1697 rhiAccumTexture = data.getRenderResult(QSSGRenderResult::Key::AccumTexture);
1698 rhiRevealageTexture = data.getRenderResult(QSSGRenderResult::Key::RevealageTexture);
1700 rhiDepthTexture = data.getRenderResult(QSSGRenderResult::Key::DepthTextureMS);
1702 rhiDepthTexture = data.getRenderResult(QSSGRenderResult::Key::DepthTexture);
1703 if (!rhiDepthTexture->isValid())
1705 auto &oitrt = data.getOitRenderContext();
1706 if (!oitrt.oitRenderTarget || oitrt.oitRenderTarget->pixelSize() != data.layerPrepResult.textureDimensions()
1707 || rhiDepthTexture->texture != oitrt.oitRenderTarget->description().depthTexture()
1708 || ps.samples != oitrt.oitRenderTarget->sampleCount()) {
1709 if (oitrt.oitRenderTarget) {
1710 rhiAccumTexture->texture->destroy();
1711 rhiRevealageTexture->texture->destroy();
1712 oitrt.oitRenderTarget->destroy();
1713 oitrt.renderPassDescriptor->destroy();
1714 oitrt.oitRenderTarget =
nullptr;
1716 const QRhiTexture::Flags textureFlags = QRhiTexture::RenderTarget;
1717 if (ps.viewCount >= 2) {
1718 rhiAccumTexture->texture = rhi->newTextureArray(QRhiTexture::RGBA16F, ps.viewCount, data.layerPrepResult.textureDimensions(), ps.samples, textureFlags);
1719 rhiRevealageTexture->texture = rhi->newTextureArray(QRhiTexture::R16F, ps.viewCount, data.layerPrepResult.textureDimensions(), ps.samples, textureFlags);
1721 rhiAccumTexture->texture = rhi->newTexture(QRhiTexture::RGBA16F, data.layerPrepResult.textureDimensions(), ps.samples, textureFlags);
1722 rhiRevealageTexture->texture = rhi->newTexture(QRhiTexture::R16F, data.layerPrepResult.textureDimensions(), ps.samples, textureFlags);
1724 rhiAccumTexture->texture->create();
1725 rhiRevealageTexture->texture->create();
1727 QRhiTextureRenderTargetDescription desc;
1728 desc.setColorAttachments({{rhiAccumTexture->texture}, {rhiRevealageTexture->texture}});
1729 desc.setDepthTexture(rhiDepthTexture->texture);
1731 if (oitrt.oitRenderTarget ==
nullptr) {
1732 oitrt.oitRenderTarget = rhi->newTextureRenderTarget(desc, QRhiTextureRenderTarget::PreserveDepthStencilContents);
1733 oitrt.renderPassDescriptor = oitrt.oitRenderTarget->newCompatibleRenderPassDescriptor();
1734 oitrt.oitRenderTarget->setRenderPassDescriptor(oitrt.renderPassDescriptor);
1735 oitrt.oitRenderTarget->create();
1737 renderTarget = oitrt.oitRenderTarget;
1740 QSSGRhiContextPrivate *rhiCtxD = QSSGRhiContextPrivate::get(rhiCtx.get());
1741 const auto &shaderCache = renderer.contextInterface()->shaderCache();
1742 clearPipeline = shaderCache->getBuiltInRhiShaders().getRhiClearMRTShader();
1744 QSSGRhiShaderResourceBindingList bindings;
1745 QVector4D clearData[2];
1746 clearData[0] = QVector4D(0.0, 0.0, 0.0, 0.0);
1747 clearData[1] = QVector4D(1.0, 1.0, 1.0, 1.0);
1749 QSSGRhiDrawCallData &dcd(rhiCtxD->drawCallData({
this, clearPipeline.get(),
nullptr, 0 }));
1750 QRhiBuffer *&ubuf = dcd.ubuf;
1751 const int ubufSize =
sizeof(clearData);
1753 ubuf = rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, ubufSize);
1757 QRhiResourceUpdateBatch *rub = rhi->nextResourceUpdateBatch();
1758 rub->updateDynamicBuffer(ubuf, 0, ubufSize, &clearData);
1759 renderer.rhiQuadRenderer()->prepareQuad(rhiCtx.get(), rub);
1761 bindings.addUniformBuffer(0, QRhiShaderResourceBinding::FragmentStage, ubuf);
1763 clearSrb = rhiCtxD->srb(bindings);
1765 ps.targetBlend[0].srcAlpha = QRhiGraphicsPipeline::One;
1766 ps.targetBlend[0].srcColor = QRhiGraphicsPipeline::One;
1767 ps.targetBlend[0].dstAlpha = QRhiGraphicsPipeline::One;
1768 ps.targetBlend[0].dstColor = QRhiGraphicsPipeline::One;
1769 ps.targetBlend[1].srcAlpha = QRhiGraphicsPipeline::Zero;
1770 ps.targetBlend[1].srcColor = QRhiGraphicsPipeline::Zero;
1771 ps.targetBlend[1].dstAlpha = QRhiGraphicsPipeline::OneMinusSrcAlpha;
1772 ps.targetBlend[1].dstColor = QRhiGraphicsPipeline::OneMinusSrcAlpha;
1774 TransparentPass::prep(*ctx, data,
this, ps, shaderFeatures, oitrt.renderPassDescriptor, sortedTransparentObjects,
true);
1775 }
else if (method == QSSGRenderLayer::OITMethod::LinkedList) {
1777 rhiCtx->commandBuffer()->resourceUpdate(
this->rub);
1778 this->rub =
nullptr;
1782 ps.flags.setFlag(QSSGRhiGraphicsPipelineState::Flag::BlendEnabled,
true);
1783 ps.flags.setFlag(QSSGRhiGraphicsPipelineState::Flag::DepthWriteEnabled,
false);
1784 ps.targetBlend[0].srcAlpha = QRhiGraphicsPipeline::One;
1785 ps.targetBlend[0].srcColor = QRhiGraphicsPipeline::SrcAlpha;
1786 ps.targetBlend[0].dstAlpha = QRhiGraphicsPipeline::OneMinusSrcAlpha;
1787 ps.targetBlend[0].dstColor = QRhiGraphicsPipeline::OneMinusSrcAlpha;
1789 shaderFeatures = data.getShaderFeatures();
1790 sortedTransparentObjects = data.getSortedTransparentRenderableObjects(*camera);
1792#ifdef QSSG_OIT_USE_BUFFERS
1793 auto &oitCtx = data.getOitRenderContext();
1794 rhiABuffer = oitCtx.aBuffer;
1795 rhiAuxBuffer = oitCtx.auxBuffer;
1796 rhiCounterBuffer = oitCtx.counterBuffer;
1798 rhiABufferImage = data.getRenderResult(QSSGRenderResult::Key::ABufferImage);
1799 rhiAuxiliaryImage = data.getRenderResult(QSSGRenderResult::Key::AuxiliaryImage);
1800 rhiCounterImage = data.getRenderResult(QSSGRenderResult::Key::CounterImage);
1802 QSize dim = data.layerPrepResult.textureDimensions();
1803 dim.setWidth(dim.width() * ps.samples);
1804 dim.setHeight(dim.height() * ps.viewCount);
1805#ifdef QSSG_OIT_USE_BUFFERS
1806 if (!rhiAuxBuffer || rhiAuxBuffer->size() != (dim.width() * dim.height() * 4u) || currentNodeCount == 0 || linkedListRequiresResize(dim))
1808 if (!rhiAuxiliaryImage->texture || rhiAuxiliaryImage->texture->pixelSize() != dim || currentNodeCount == 0 || linkedListRequiresResize(dim))
1811 quint32 extraNodeCount = 0;
1812#ifdef QSSG_OIT_USE_BUFFERS
1813 if (rhiAuxBuffer && rhiAuxBuffer->size() != (dim.width() * dim.height() * 4u)) {
1814 if (rhiAuxBuffer->size() < (dim.width() * dim.height() * 4u))
1815 extraNodeCount = ensureFreeNodes((dim.width() * dim.height() * 4u) - rhiAuxBuffer->size(), 32u * 1024u);
1816 rhiAuxBuffer->destroy();
1817 rhiAuxBuffer =
nullptr;
1820 if (rhiABufferImage->texture) {
1821 const auto s = rhiAuxiliaryImage->texture->pixelSize();
1822 if (s.width() * s.height() < dim.width() * dim.height())
1823 extraNodeCount = ensureFreeNodes(dim.width() * dim.height() - s.width() * s.height(), 32u * 1024u);
1824 rhiABufferImage->texture->destroy();
1825 rhiAuxiliaryImage->texture->destroy();
1829 if (reportedNodeCount) {
1831 currentNodeCount = ensureFreeNodes(reportedNodeCount + extraNodeCount, dim.width() * dim.height() / 2);
1833 quint32 size = RenderHelpers::rhiCalculateABufferSize(data.layerPrepResult.textureDimensions(), 4 * ps.samples * ps.viewCount);
1834 currentNodeCount = ensureFreeNodes(size * size, 32u * 1024u);
1836 data.layer.oitNodeCount = currentNodeCount;
1838#ifdef QSSG_OIT_USE_BUFFERS
1839 if (rhiABuffer && currentNodeCount * 16 != rhiABuffer->size()) {
1840 rhiABuffer->destroy();
1841 rhiABuffer =
nullptr;
1844 rhiABuffer = rhi->newBuffer(QRhiBuffer::Static, QRhiBuffer::StorageBuffer, currentNodeCount * 16);
1845 rhiABuffer->create();
1847 if (!rhiAuxBuffer) {
1848 rhiAuxBuffer = rhi->newBuffer(QRhiBuffer::Static, QRhiBuffer::StorageBuffer, dim.width() * dim.height() * 4);
1849 rhiAuxBuffer->create();
1851 if (!rhiCounterBuffer) {
1852 rhiCounterBuffer = rhi->newBuffer(QRhiBuffer::Static, QRhiBuffer::StorageBuffer, 4);
1853 rhiCounterBuffer->create();
1854 oitCtx.counterBuffer = rhiCounterBuffer;
1856 oitCtx.aBuffer = rhiABuffer;
1857 oitCtx.auxBuffer = rhiAuxBuffer;
1859 quint32 sizeWithLayers = RenderHelpers::rhiCalculateABufferSize(currentNodeCount);
1860 const QRhiTexture::Flags textureFlags = QRhiTexture::UsedWithLoadStore;
1861 rhiABufferImage->texture = rhi->newTexture(QRhiTexture::RGBA32UI, QSize(sizeWithLayers, sizeWithLayers), 1, textureFlags);
1862 rhiABufferImage->texture->create();
1863 rhiAuxiliaryImage->texture = rhi->newTexture(QRhiTexture::R32UI, dim, 1, textureFlags);
1864 rhiAuxiliaryImage->texture->create();
1865 if (!rhiCounterImage->texture) {
1866 rhiCounterImage->texture = rhi->newTexture(QRhiTexture::R32UI, QSize(1, 1), 1, textureFlags | QRhiTexture::UsedAsTransferSource);
1867 rhiCounterImage->texture->create();
1869 auto &oitrt = data.getOitRenderContext();
1870 readbackImage = rhi->newTexture(QRhiTexture::R32UI, QSize(1, 1), 1, QRhiTexture::UsedAsTransferSource);
1876 QRhiResourceUpdateBatch *rub = rhiCtx->rhi()->nextResourceUpdateBatch();
1878 QSSGRhiContextPrivate *rhiCtxD = QSSGRhiContextPrivate::get(rhiCtx.get());
1879 const auto &shaderCache = renderer.contextInterface()->shaderCache();
1880#ifdef QSSG_OIT_USE_BUFFERS
1881 clearPipeline = shaderCache->getBuiltInRhiShaders().getRhiClearBufferShader();
1883 clearPipeline = shaderCache->getBuiltInRhiShaders().getRhiClearImageShader();
1885 QSSGRhiShaderResourceBindingList bindings;
1886 quint32 clearImageData[8] = {0};
1888 QSSGRhiDrawCallData &dcd(rhiCtxD->drawCallData({
this, clearPipeline.get(),
nullptr, 0 }));
1889 QRhiBuffer *&ubuf = dcd.ubuf;
1890 const int ubufSize =
sizeof(clearImageData);
1892 ubuf = rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, ubufSize);
1896 clearImageData[4] = data.layerPrepResult.textureDimensions().width();
1897 clearImageData[5] = data.layerPrepResult.textureDimensions().height();
1898 clearImageData[6] = ps.samples;
1899 clearImageData[7] = ps.viewCount;
1901 rub->updateDynamicBuffer(ubuf, 0, ubufSize, clearImageData);
1903#ifdef QSSG_OIT_USE_BUFFERS
1904 rub->uploadStaticBuffer(rhiCounterBuffer, 0, 4, &zero);
1906 rub->uploadTexture(rhiCounterImage->texture, {{0, 0, {&zero, 4}}});
1909 bindings.addUniformBuffer(0, QRhiShaderResourceBinding::FragmentStage, ubuf);
1910#ifdef QSSG_OIT_USE_BUFFERS
1911 bindings.addStorageBuffer(1, QRhiShaderResourceBinding::FragmentStage, rhiAuxBuffer);
1913 bindings.addImageStore(1, QRhiShaderResourceBinding::FragmentStage, rhiAuxiliaryImage->texture, 0);
1916 clearSrb = rhiCtxD->srb(bindings);
1918 renderer.rhiQuadRenderer()->prepareQuad(rhiCtx.get(), rub);
1920 TransparentPass::prep(*ctx, data,
this, ps, shaderFeatures, rhiCtx->mainRenderPassDescriptor(), sortedTransparentObjects,
true);
1926 auto *ctx = renderer.contextInterface();
1927 const auto &rhiCtx = ctx->rhiContext();
1928 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(),
return);
1929 QRhiCommandBuffer *cb = rhiCtx->commandBuffer();
1931 if (method == QSSGRenderLayer::OITMethod::WeightedBlended) {
1932 if (Q_LIKELY(renderTarget)) {
1933 cb->beginPass(renderTarget, Qt::black, {});
1935 QRhiShaderResourceBindings *srb = clearSrb;
1937 ps.flags.setFlag(QSSGRhiGraphicsPipelineState::Flag::BlendEnabled,
false);
1938 QSSGRhiGraphicsPipelineStatePrivate::setShaderPipeline(ps, clearPipeline.get());
1939 renderer.rhiQuadRenderer()->recordRenderQuad(rhiCtx.get(), &ps, srb, renderTarget->renderPassDescriptor(), {});
1940 ps.flags.setFlag(QSSGRhiGraphicsPipelineState::Flag::BlendEnabled,
true);
1942 cb->debugMarkBegin(QByteArrayLiteral(
"Quick3D render order-independent alpha"));
1943 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderPass);
1944 Q_TRACE(QSSG_renderPass_entry, QStringLiteral(
"Quick3D render order-independent alpha"));
1945 ps.flags.setFlag(QSSGRhiGraphicsPipelineState::Flag::DepthTestEnabled,
true);
1946 ps.flags.setFlag(QSSGRhiGraphicsPipelineState::Flag::DepthWriteEnabled,
false);
1947 TransparentPass::render(*ctx, ps, sortedTransparentObjects);
1949 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral(
"transparent_order_independent_pass"));
1950 Q_TRACE(QSSG_renderPass_exit);
1954 }
else if (method == QSSGRenderLayer::OITMethod::LinkedList) {
1955 cb->debugMarkBegin(QByteArrayLiteral(
"Quick3D render alpha"));
1956 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderPass);
1957 Q_TRACE(QSSG_renderPass_entry, QStringLiteral(
"Quick3D render alpha"));
1959 QRhiShaderResourceBindings *srb = clearSrb;
1961 ps.flags.setFlag(QSSGRhiGraphicsPipelineState::Flag::BlendEnabled,
true);
1962 QSSGRhiGraphicsPipelineStatePrivate::setShaderPipeline(ps, clearPipeline.get());
1963 renderer.rhiQuadRenderer()->recordRenderQuad(rhiCtx.get(), &ps, srb, rhiCtx->mainRenderPassDescriptor(), {});
1965 TransparentPass::render(*ctx, ps, sortedTransparentObjects);
1966#ifdef QSSG_OIT_USE_BUFFERS
1967 QRhiResourceUpdateBatch *rub = rhiCtx->rhi()->nextResourceUpdateBatch();
1968 QRhiReadbackResult *result =
nullptr;
1969 if (results.size() > 1) {
1970 result = results.takeLast();
1971 result->pixelSize = {};
1973 result->format = QRhiTexture::UnknownFormat;
1975 result =
new QRhiReadbackResult();
1977 const auto completedFunc = [
this, result](){
1979 const quint32 *d =
reinterpret_cast<
const quint32 *>(result->data.constData());
1980 quint32 nodeCount = *d;
1982 this->reportedNodeCount = ensureFreeNodes(nodeCount, 32u * 1024u);
1983 this->results.append(result);
1986 result->completed = completedFunc;
1987 rub->readBackBuffer(rhiCounterBuffer, 0, 4, result);
1990 QRhiResourceUpdateBatch *rub = rhiCtx->rhi()->nextResourceUpdateBatch();
1992 QRhiReadbackDescription rbdesc;
1994 QRhiReadbackResult *result =
nullptr;
1995 if (results.size() > 1) {
1996 result = results.takeLast();
1997 result->pixelSize = {};
1999 result->format = QRhiTexture::UnknownFormat;
2001 result =
new QRhiReadbackResult();
2003 const auto completedFunc = [
this, result](){
2005 const quint32 *d =
reinterpret_cast<
const quint32 *>(result->data.constData());
2006 quint32 nodeCount = *d;
2008 this->reportedNodeCount = ensureFreeNodes(nodeCount, 32u * 1024u);
2009 this->results.append(result);
2012 result->completed = completedFunc;
2013 rub->readBackTexture(rbdesc, result);
2017 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral(
"transparent_order_independent_pass"));
2018 Q_TRACE(QSSG_renderPass_exit);
2106 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
2107 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(),
return);
2108 QRhiCommandBuffer *cb = rhiCtx->commandBuffer();
2110 QSSGRhiContextPrivate *rhiCtxD = QSSGRhiContextPrivate::get(rhiCtx.get());
2112 if (!rhiAccumTexture->texture || !rhiRevealageTexture->texture)
2115 if (method == QSSGRenderLayer::OITMethod::WeightedBlended) {
2116 QSSGRhiShaderResourceBindingList bindings;
2118 QRhiSampler *sampler = rhiCtx->sampler({ QRhiSampler::Nearest,
2119 QRhiSampler::Nearest,
2121 QRhiSampler::ClampToEdge,
2122 QRhiSampler::ClampToEdge,
2123 QRhiSampler::ClampToEdge });
2124 bindings.addTexture(1, QRhiShaderResourceBinding::FragmentStage, rhiAccumTexture->texture, sampler);
2125 bindings.addTexture(2, QRhiShaderResourceBinding::FragmentStage, rhiRevealageTexture->texture, sampler);
2127 compositeSrb = rhiCtxD->srb(bindings);
2129 QRhiShaderResourceBindings *srb = compositeSrb;
2132 cb->debugMarkBegin(QByteArrayLiteral(
"Quick3D revealage"));
2133 QSSGRhiGraphicsPipelineStatePrivate::setShaderPipeline(ps, compositeShaderPipeline.get());
2134 ps.flags.setFlag(QSSGRhiGraphicsPipelineState::Flag::BlendEnabled,
true);
2135 renderer.rhiQuadRenderer()->recordRenderQuad(rhiCtx.get(), &ps, srb, rhiCtx->mainRenderPassDescriptor(),
2136 { QSSGRhiQuadRenderer::UvCoords | QSSGRhiQuadRenderer::DepthTest | QSSGRhiQuadRenderer::PremulBlend});
2137 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral(
"revealage"));
2139 }
else if (method == QSSGRenderLayer::OITMethod::LinkedList) {
2140 QSSGRhiShaderResourceBindingList bindings;
2142 QSSGRhiContextPrivate *rhiCtxD = QSSGRhiContextPrivate::get(rhiCtx.get());
2143 QSSGRhiDrawCallData &dcd(rhiCtxD->drawCallData({
this,
nullptr,
nullptr, 0 }));
2144 QRhiBuffer *&ubuf = dcd.ubuf;
2146 bindings.addUniformBuffer(0, QRhiShaderResourceBinding::FragmentStage, ubuf);
2147#ifdef QSSG_OIT_USE_BUFFERS
2148 bindings.addStorageBuffer(1, QRhiShaderResourceBinding::FragmentStage, rhiABuffer);
2149 bindings.addStorageBuffer(2, QRhiShaderResourceBinding::FragmentStage, rhiAuxBuffer);
2151 bindings.addImageLoad(1, QRhiShaderResourceBinding::FragmentStage, rhiABufferImage->texture, 0);
2152 bindings.addImageLoad(2, QRhiShaderResourceBinding::FragmentStage, rhiAuxiliaryImage->texture, 0);
2155 compositeSrb = rhiCtxD->srb(bindings);
2157 QRhiShaderResourceBindings *srb = compositeSrb;
2160 cb->debugMarkBegin(QByteArrayLiteral(
"Quick3D oit-composite"));
2161 QSSGRhiGraphicsPipelineStatePrivate::setShaderPipeline(ps, compositeShaderPipeline.get());
2162 ps.flags.setFlag(QSSGRhiGraphicsPipelineState::Flag::BlendEnabled,
true);
2163 renderer.rhiQuadRenderer()->recordRenderQuad(rhiCtx.get(), &ps, srb, rhiCtx->mainRenderPassDescriptor(),
2164 { QSSGRhiQuadRenderer::UvCoords | QSSGRhiQuadRenderer::DepthTest | QSSGRhiQuadRenderer::PremulBlend});
2165 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral(
"oit-composite"));
2263 QSSGRenderUserPass *passNode,
2264 std::vector<UserPassData> &outData,
2265 QSSGRhiRenderableTextureV2Ptr renderableTexture)
2269 const bool isTopLevelPass = (renderableTexture ==
nullptr);
2271 QSSGRenderCamera *camera = data.renderedCameras[0];
2272 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
2274 const QSize targetSize = data.layerPrepResult.textureDimensions();
2276 static const auto needsRebuild = [](QRhiTexture *texture,
const QSize &size, QRhiTexture::Format format) {
2277 return !texture || texture->pixelSize() != size || texture->format() != format;
2280 qCDebug(lcUserRenderPass,
"renderPrep in UserRenderPass");
2282 const QSSGResourceId currentPassId = QSSGRenderGraphObjectUtils::getResourceId(*passNode);
2283 if (visitedPasses.find(currentPassId) != visitedPasses.end()) {
2284 qWarning(
"UserRenderPass: Circular dependency detected in SubRenderPass chain. Ignoring pass.");
2289 if (visitedPasses.size() >= MAX_SUBPASS_DEPTH) {
2290 qWarning(
"UserRenderPass: Maximum SubRenderPass nesting depth (%zu) exceeded. Ignoring pass.", MAX_SUBPASS_DEPTH);
2294 visitedPasses.insert(currentPassId);
2297 currentPassData.clearColor = passNode->clearColor;
2298 currentPassData.depthStencilClearValue = passNode->depthStencilClearValue;
2300 renderableTexture = currentPassData.renderableTexture = data.requestUserRenderPassManager()->getOrCreateRenderableTexture(*passNode);
2302 currentPassData.renderableTexture = renderableTexture;
2304 QSSGRenderableObjectList &renderables = currentPassData.renderables;
2305 QSSGRhiGraphicsPipelineState &ps = currentPassData.ps;
2306 const auto &renderTarget = currentPassData.renderableTexture;
2309 ps = data.getPipelineState();
2311 bool renderablesFiltered =
false;
2313 bool needsDepthStencilRenderBuffer =
false;
2314 QSSGAllocateTexturePtr depthTextureAllocCommand;
2316 QVarLengthArray<QSSGColorAttachment *, 16> colorAttachments;
2317 QVarLengthArray<QSSGResourceId, 4> subPassIds;
2320 for (
const QSSGCommand *theCommand : std::as_const(passNode->commands)) {
2323 qCDebug(lcUserRenderPass) <<
"Exec. command: >" << theCommand->typeAsString() <<
"--" << theCommand->debugString();
2325 switch (theCommand->m_type) {
2326 case CommandType::ColorAttachment:
2328 const QSSGColorAttachment *colorAttachCmd =
static_cast<
const QSSGColorAttachment *>(theCommand);
2329 colorAttachments.push_back(
const_cast<QSSGColorAttachment *>(colorAttachCmd));
2332 case CommandType::DepthTextureAttachment:
2334 QSSG_ASSERT(depthTextureAllocCommand ==
nullptr,
break);
2335 const QSSGDepthTextureAttachment *depthAttachCmd =
static_cast<
const QSSGDepthTextureAttachment *>(theCommand);
2336 needsDepthStencilRenderBuffer =
false;
2337 depthTextureAllocCommand = depthAttachCmd->m_textureCmd;
2340 case CommandType::AddShaderDefine:
2342 const auto *defineCmd =
static_cast<
const QSSGAddShaderDefine *>(theCommand);
2343 const auto &defineName = defineCmd->m_name;
2344 if (defineName.size() > 0) {
2345 QByteArray value = QByteArray::number(defineCmd->m_value);
2346 currentPassData.shaderDefines.push_back({ defineName, value });
2350 case CommandType::RenderablesFilter:
2352 auto filterCommand =
static_cast<
const QSSGRenderablesFilterCommand *>(theCommand);
2356 enum RenderableType : quint8 {
2362 if (filterCommand->renderableTypes & RenderableType::Opaque)
2363 renderables = data.getSortedOpaqueRenderableObjects(*camera, 0, filterCommand->layerMask);
2364 if (filterCommand->renderableTypes & RenderableType::Transparent)
2365 renderables += data.getSortedTransparentRenderableObjects(*camera, 0, filterCommand->layerMask);
2369 renderablesFiltered =
true;
2373 case CommandType::PipelineStateOverride:
2375 auto pipelineCommand =
static_cast<
const QSSGPipelineStateOverrideCommand *>(theCommand);
2376 if (pipelineCommand->m_depthTestEnabled)
2377 ps.flags.setFlag(QSSGRhiGraphicsPipelineState::Flag::DepthTestEnabled, *pipelineCommand->m_depthTestEnabled);
2378 if (pipelineCommand->m_depthWriteEnabled)
2379 ps.flags.setFlag(QSSGRhiGraphicsPipelineState::Flag::DepthWriteEnabled, *pipelineCommand->m_depthWriteEnabled);
2380 if (pipelineCommand->m_blendEnabled)
2381 ps.flags.setFlag(QSSGRhiGraphicsPipelineState::Flag::BlendEnabled, *pipelineCommand->m_blendEnabled);
2382 if (pipelineCommand->m_usesStencilReference)
2383 ps.flags.setFlag(QSSGRhiGraphicsPipelineState::Flag::UsesStencilRef, *pipelineCommand->m_usesStencilReference);
2384 if (pipelineCommand->m_usesScissor)
2385 ps.flags.setFlag(QSSGRhiGraphicsPipelineState::Flag::UsesScissor, *pipelineCommand->m_usesScissor);
2386 if (pipelineCommand->m_depthFunction)
2387 ps.depthFunc = *pipelineCommand->m_depthFunction;
2388 if (pipelineCommand->m_cullMode) {
2389 ps.cullMode = *pipelineCommand->m_cullMode;
2390 ps.userSetCullMode =
true;
2392 if (pipelineCommand->m_polygonMode)
2393 ps.polygonMode = *pipelineCommand->m_polygonMode;
2394 if (pipelineCommand->m_stencilOpFrontState)
2395 ps.stencilOpFrontState = *pipelineCommand->m_stencilOpFrontState;
2396 if (pipelineCommand->m_stencilWriteMask)
2397 ps.stencilWriteMask = *pipelineCommand->m_stencilWriteMask;
2398 if (pipelineCommand->m_stencilReference)
2399 ps.stencilRef = *pipelineCommand->m_stencilReference;
2400 if (pipelineCommand->m_viewport)
2401 ps.viewport = *pipelineCommand->m_viewport;
2402 if (pipelineCommand->m_scissor)
2403 ps.scissor = *pipelineCommand->m_scissor;
2404 if (pipelineCommand->m_targetBlend0)
2405 ps.targetBlend[0] = *pipelineCommand->m_targetBlend0;
2406 if (pipelineCommand->m_targetBlend1)
2407 ps.targetBlend[1] = *pipelineCommand->m_targetBlend1;
2408 if (pipelineCommand->m_targetBlend2)
2409 ps.targetBlend[2] = *pipelineCommand->m_targetBlend2;
2410 if (pipelineCommand->m_targetBlend3)
2411 ps.targetBlend[3] = *pipelineCommand->m_targetBlend3;
2412 if (pipelineCommand->m_targetBlend4)
2413 ps.targetBlend[4] = *pipelineCommand->m_targetBlend4;
2414 if (pipelineCommand->m_targetBlend5)
2415 ps.targetBlend[5] = *pipelineCommand->m_targetBlend5;
2416 if (pipelineCommand->m_targetBlend6)
2417 ps.targetBlend[6] = *pipelineCommand->m_targetBlend6;
2418 if (pipelineCommand->m_targetBlend7)
2419 ps.targetBlend[7] = *pipelineCommand->m_targetBlend7;
2422 case CommandType::DepthStencilAttachment:
2424 QSSG_ASSERT(depthTextureAllocCommand ==
nullptr,
break);
2425 needsDepthStencilRenderBuffer =
true;
2427 case CommandType::SubRenderPass:
2429 auto subPassCommand =
static_cast<
const QSSGSubRenderPass *>(theCommand);
2430 if (subPassCommand && subPassCommand->m_userPassId != QSSGResourceId::Invalid)
2431 subPassIds.append(subPassCommand->m_userPassId);
2435 qWarning() <<
"Effect command" << theCommand->typeAsString() <<
"not implemented";
2440 if (colorAttachments.size() > 4) {
2441 colorAttachments.resize(4);
2442 qWarning() <<
"UserRenderPass supports up to 4 color attachments only.";
2447 if (isTopLevelPass) {
2449 bool needsBuild = !renderTarget->isValid();
2451 const qsizetype oldAttachmentCount = renderTarget->colorAttachmentCount();
2453 if (oldAttachmentCount != colorAttachments.size())
2460 if (renderTarget->getRenderTarget() && renderTarget->getRenderTarget()->flags() != passNode->renderTargetFlags)
2466 for (
int i = 0; i != oldAttachmentCount; ++i) {
2467 const auto &colorAttachment = colorAttachments.at(i);
2468 QSSG_ASSERT(colorAttachment !=
nullptr,
continue);
2469 const auto expectedFormat = QSSGBufferManager::toRhiFormat(colorAttachment->format());
2470 const auto &texture = renderTarget->getColorTexture(i);
2471 needsBuild = needsBuild || needsRebuild(&(*texture->texture()), targetSize, expectedFormat);
2475 if (needsDepthStencilRenderBuffer != (renderTarget->getDepthStencil() !=
nullptr))
2479 if (depthTextureAllocCommand) {
2480 const auto format = QSSGBufferManager::toRhiFormat(depthTextureAllocCommand->format());
2481 const auto &depthTextureWrapper = renderTarget->getDepthTexture();
2482 needsBuild = depthTextureWrapper ==
nullptr;
2483 needsBuild = needsBuild || needsRebuild(&(*depthTextureWrapper->texture()), targetSize, format);
2485 if (renderTarget->getDepthTexture() !=
nullptr)
2491 const auto &rt = renderTarget->getRenderTarget();
2492 if (rt && rt->flags() != passNode->renderTargetFlags)
2498 renderTarget->reset();
2500 QRhiTextureRenderTargetDescription rtDesc;
2503 const qsizetype colorAttachmentCount = qMax<qsizetype>(colorAttachments.size(), 1);
2505 bool createSucceeded =
true;
2506 bool colorAllocatorsNeedsUpdate =
false;
2510 QVarLengthArray<QRhiTexture *, 4> textures;
2511 for (qsizetype i = 0; i < colorAttachmentCount && createSucceeded ; ++i) {
2512 const auto &colorAttCmd = colorAttachments.at(i);
2513 const auto &name = colorAttCmd->m_name;
2514 const auto format = QSSGBufferManager::toRhiFormat(colorAttCmd->format());
2515 const auto &allocateTexCmd = colorAttCmd->m_textureCmd;
2516 if (allocateTexCmd->texture() && !needsRebuild(&(*allocateTexCmd->texture()->texture()), targetSize, format)) {
2519 textures.push_back(allocateTexCmd->texture()->texture().get());
2521 auto *tex = rhiCtx->rhi()->newTexture(format, targetSize, ps.samples, QRhiTexture::RenderTarget);
2523 createSucceeded = createSucceeded && tex->create();
2524 textures.push_back(tex);
2528 colorAllocatorsNeedsUpdate =
true;
2532 rtDesc.setColorAttachments(textures.cbegin(), textures.cend());
2535 if (needsDepthStencilRenderBuffer) {
2536 auto renderBuffer = rhiCtx->rhi()->newRenderBuffer(QRhiRenderBuffer::DepthStencil, targetSize, ps.samples);
2537 if (renderBuffer->create())
2538 rtDesc.setDepthStencilBuffer(renderBuffer);
2539 }
else if (depthTextureAllocCommand) {
2540 const auto format = QSSGBufferManager::toRhiFormat(depthTextureAllocCommand->format());
2541 if (depthTextureAllocCommand->texture() && !needsRebuild(&(*depthTextureAllocCommand->texture()->texture()), targetSize, format)) {
2542 rtDesc.setDepthTexture(depthTextureAllocCommand->texture()->texture().get());
2545 QRhiTexture *depthTex = rhiCtx->rhi()->newTexture(format, targetSize, ps.samples, QRhiTexture::RenderTarget);
2546 if (depthTex->create())
2547 rtDesc.setDepthTexture(depthTex);
2551 if (createSucceeded) {
2553 renderTarget->setDescription(rhiCtx->rhi(),
std::move(rtDesc), passNode->renderTargetFlags);
2556 if (colorAllocatorsNeedsUpdate) {
2557 for (qsizetype i = 0; i < colorAttachmentCount; ++i) {
2558 const auto &colorAttCmd = colorAttachments.at(i);
2559 const auto &allocateTexCmd = colorAttCmd->m_textureCmd;
2560 allocateTexCmd->setTexture(renderTarget->getColorTexture(i));
2564 if (depthTextureAllocCommand)
2565 depthTextureAllocCommand->setTexture(renderTarget->getDepthTexture());
2568 renderTarget->resetRenderTarget();
2569 qWarning() <<
"Failed to create textures for UserRenderPass";
2575 Q_ASSERT(renderTarget->isValid());
2577 ps.colorAttachmentCount =
int(renderTarget->colorAttachmentCount());
2580 for (
const auto &subPassId : std::as_const(subPassIds)) {
2581 QSSGRenderUserPass *userPassNode = QSSGRenderGraphObjectUtils::getResource<QSSGRenderUserPass>(subPassId);
2582 QSSG_ASSERT(userPassNode && userPassNode->type == QSSGRenderGraphObject::Type::RenderPass,
continue);
2583 prepareSubPass(renderer, data, userPassNode, currentPassData.subPassData, currentPassData.renderableTexture);
2586 if (passNode->passMode == QSSGRenderUserPass::PassModes::UserPass) {
2588 if (!renderablesFiltered && renderables.isEmpty())
2589 renderables = data.getSortedOpaqueRenderableObjects(*camera);
2591 if (passNode->materialMode == QSSGRenderUserPass::MaterialModes::AugmentMaterial) {
2595 QSSG_ASSERT(shaderAugmentation.outputs.size() == 0, shaderAugmentation.outputs.clear());
2596 shaderAugmentation.defines =
std::move(currentPassData.shaderDefines);
2598 for (
int i = 0, end = colorAttachments.size(); i < end; ++i) {
2599 const auto &colorAttCmd = colorAttachments.at(i);
2600 const auto &name = colorAttCmd->m_name;
2601 if (name.size() > 0)
2602 shaderAugmentation.outputs.push_back(name);
2604 shaderAugmentation.outputs.push_back(getDefaultOutputName(size_t(i)));
2607 QSSGShaderFeatures shaderFeatures = data.getShaderFeatures();
2608 shaderFeatures.disableTonemapping();
2610 currentPassData.index = RenderHelpers::rhiPrepareAugmentedUserPass(&(*rhiCtx),
this, ps, renderTarget->getRenderPassDescriptor().get(), shaderAugmentation, data, renderables, shaderFeatures);
2611 }
else if (passNode->materialMode == QSSGRenderUserPass::MaterialModes::OverrideMaterial) {
2613 QSSGShaderFeatures shaderFeatures = data.getShaderFeatures();
2614 shaderFeatures.disableTonemapping();
2616 currentPassData.index = RenderHelpers::rhiPrepareOverrideMaterialUserPass(&(*rhiCtx),
this, ps, renderTarget->getRenderPassDescriptor().get(), passNode->overrideMaterial, data, renderables, shaderFeatures);
2620 QSSGShaderFeatures shaderFeatures = data.getShaderFeatures();
2621 shaderFeatures.disableTonemapping();
2622 currentPassData.index = RenderHelpers::rhiPrepareOriginalMaterialUserPass(&(*rhiCtx),
this, ps, renderTarget->getRenderPassDescriptor().get(), data, renderables, shaderFeatures);
2624 outData.push_back(currentPassData);
2627 if (passNode->passMode == QSSGRenderUserPass::PassModes::SkyboxPass) {
2628 if (rhiCtx->rhi()->isFeatureSupported(QRhi::TexelFetch)) {
2629 if (data.layer.background == QSSGRenderLayer::Background::SkyBoxCubeMap && data.layer.skyBoxCubeMap) {
2630 if (!currentPassData.skyboxCubeMapPass)
2633 currentPassData.skyboxCubeMapPass->skipTonemapping =
true;
2634 currentPassData.skyboxCubeMapPass->renderPrep(renderer, data);
2635 currentPassData.skyboxCubeMapPass->ps.samples = ps.samples;
2636 currentPassData.skyboxCubeMapPass->rpDesc = renderTarget->getRenderPassDescriptor().get();
2638 currentPassData.skyboxPass =
std::nullopt;
2639 }
else if ((data.layer.background == QSSGRenderLayer::Background::SkyBox && data.layer.lightProbe)
2640 || (data.layer.background == QSSGRenderLayer::Background::SkyMaterial && data.layer.skyMaterial)) {
2641 if (!currentPassData.skyboxPass)
2644 currentPassData.skyboxPass->skipTonemapping =
true;
2645 currentPassData.skyboxPass->renderPrep(renderer, data);
2646 currentPassData.skyboxPass->ps.samples = ps.samples;
2647 currentPassData.skyboxPass->rpDesc = renderTarget->getRenderPassDescriptor().get();
2649 currentPassData.skyboxCubeMapPass =
std::nullopt;
2651 outData.push_back(currentPassData);
2653 }
else if (passNode->passMode == QSSGRenderUserPass::PassModes::Item2DPass) {
2654 if (!currentPassData.item2DPass)
2656 const bool hasItem2Ds = (data.item2DsView.size() > 0);
2659 QSSGRhiContextPrivate *rhiCtxD = QSSGRhiContextPrivate::get(renderer.contextInterface()->rhiContext().get());
2660 QRhiRenderTarget *prevRenderTarget = rhiCtx->renderTarget();
2661 rhiCtxD->setRenderTarget(renderTarget->getRenderTarget().get());
2662 currentPassData.item2DPass->renderPrep(renderer, data);
2664 rhiCtxD->setRenderTarget(prevRenderTarget);
2665 outData.push_back(currentPassData);