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);
1186 const auto &ctx = *renderer.contextInterface();
1187 const auto &rhiCtx = ctx.rhiContext();
1188 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(),
return);
1189 QSSG_ASSERT(!data.renderedCameras.isEmpty(),
return);
1190 QSSG_ASSERT(data.renderedCameras.count() == data.layer.viewCount,
return);
1191 layer = &data.layer;
1196 rpDesc = rhiCtx->mainRenderPassDescriptor();
1197 ps = data.getPipelineState();
1198 ps.samples = rhiCtx->mainPassSampleCount();
1199 ps.viewCount = data.layer.viewCount;
1200 ps.polygonMode = QRhiGraphicsPipeline::Fill;
1203 skipTonemapping = layer->firstEffect !=
nullptr;
1205 QRhi *rhi = rhiCtx->rhi();
1206 QSSGRenderSkyMaterial &skyMaterial = *layer->skyMaterial;
1207 const int viewCount = data.layer.viewCount;
1209 const QSSGRenderLayer::TonemapMode tonemapMode =
1210 skipTonemapping && (layer->tonemapMode != QSSGRenderLayer::TonemapMode::Custom)
1211 ? QSSGRenderLayer::TonemapMode::None
1212 : layer->tonemapMode;
1213 QSSGShaderFeatures tonemapFeatures;
1214 quint32 tonemapKey = 0;
1215 skyMaterialTonemapFeatures(tonemapMode, tonemapFeatures, tonemapKey);
1217 pipeline = skyMaterial.ensureBackgroundPipeline(ctx, tonemapFeatures, tonemapKey, viewCount);
1225 const QMatrix3x3 o = layer->lightProbeSettings.probeOrientation;
1226 const QMatrix4x4 orientation(o(0, 0), o(0, 1), o(0, 2), 0.0f,
1227 o(1, 0), o(1, 1), o(1, 2), 0.0f,
1228 o(2, 0), o(2, 1), o(2, 2), 0.0f,
1229 0.0f, 0.0f, 0.0f, 1.0f);
1230 QVarLengthArray<QMatrix4x4, 2> inverseProjections;
1231 QVarLengthArray<QMatrix4x4, 2> viewRotations;
1232 for (
int v = 0; v < viewCount; ++v) {
1233 const QSSGRenderCamera &camera = *data.renderedCameras[v];
1234 inverseProjections.append(camera.projection.inverted());
1235 QMatrix4x4 cameraRotation = data.getGlobalTransform(camera);
1236 cameraRotation.setColumn(3, QVector4D(0.0f, 0.0f, 0.0f, 1.0f));
1237 viewRotations.append(orientation * cameraRotation);
1239 const float adjustY = rhi->isYUpInNDC() ? 1.0f : -1.0f;
1240 const float exposure = layer->lightProbeSettings.probeExposure;
1242 skyMaterial.updateBackgroundUniforms(ctx, inverseProjections, viewRotations, adjustY, exposure);
1244 QSSGRhiContextPrivate *rhiCtxD = QSSGRhiContextPrivate::get(rhiCtx.get());
1245 backgroundSrb = rhiCtxD->srb(skyMaterial.backgroundBindings);
1247 switch (skyMaterial.skyboxMode) {
1248 case QSSGRenderSkyMaterial::SkyboxMode::ScreenSpaceHalf:
1251 case QSSGRenderSkyMaterial::SkyboxMode::ScreenSpaceQuarter:
1254 case QSSGRenderSkyMaterial::SkyboxMode::ScreenSpaceFull:
1255 case QSSGRenderSkyMaterial::SkyboxMode::Cubemap:
1260 renderer.rhiQuadRenderer()->prepareQuad(rhiCtx.get(),
nullptr);
1265 const std::array<
float, 4> vp = ps.viewport.viewport();
1266 const QSize fullSize(
int(vp.at(2)),
int(vp.at(3)));
1267 const QSize targetSize = (fullSize / qreal(
scaleDivisor)).expandedTo(QSize(1, 1));
1268 const bool multiView = viewCount >= 2;
1269 const int wantArraySize = multiView ? viewCount : 0;
1271 offscreenTexture = data.getRenderResult(QSSGRenderResult::Key::SkyMaterialBackgroundTexture);
1272 QSSGRhiRenderableTexture *tex = offscreenTexture;
1273 if (!tex->texture || tex->texture->pixelSize() != targetSize || tex->texture->arraySize() != wantArraySize) {
1275 tex->texture = multiView ? rhi->newTextureArray(QRhiTexture::RGBA16F, viewCount, targetSize, 1, QRhiTexture::RenderTarget)
1276 : rhi->newTexture(QRhiTexture::RGBA16F, targetSize, 1, QRhiTexture::RenderTarget);
1277 if (!tex->texture->create()) {
1278 qWarning(
"Failed to build SkyMaterial screen-space background texture");
1280 offscreenTexture =
nullptr;
1283 QRhiColorAttachment att(tex->texture);
1284 att.setMultiViewCount(viewCount);
1285 QRhiTextureRenderTargetDescription desc;
1286 desc.setColorAttachments({ att });
1287 tex->rt = rhi->newTextureRenderTarget(desc);
1288 tex->rt->setName(QByteArrayLiteral(
"SkyMaterial screen-space background"));
1289 tex->rpDesc = tex->rt->newCompatibleRenderPassDescriptor();
1290 tex->rt->setRenderPassDescriptor(tex->rpDesc);
1291 if (!tex->rt->create()) {
1292 qWarning(
"Failed to build SkyMaterial screen-space background render target");
1294 offscreenTexture =
nullptr;
1299 QSSGRhiGraphicsPipelineState offscreenPs;
1300 offscreenPs.viewport = QRhiViewport(0, 0,
float(targetSize.width()),
float(targetSize.height()));
1301 offscreenPs.samples = 1;
1302 offscreenPs.viewCount = viewCount;
1303 offscreenPs.polygonMode = QRhiGraphicsPipeline::Fill;
1304 QSSGRhiGraphicsPipelineStatePrivate::setShaderPipeline(offscreenPs, pipeline.get());
1305 renderer.rhiQuadRenderer()->recordRenderQuadPass(rhiCtx.get(), &offscreenPs, backgroundSrb,
1306 offscreenTexture->rt, QSSGRhiQuadRenderer::RenderBehind);
1675 auto *ctx = renderer.contextInterface();
1676 const auto &rhiCtx = ctx->rhiContext();
1677 auto *rhi = rhiCtx->rhi();
1679 QSSG_ASSERT(!data.renderedCameras.isEmpty() && data.renderedCameraData.has_value() ,
return);
1680 QSSGRenderCamera *camera = data.renderedCameras[0];
1682 ps = data.getPipelineState();
1683 ps.samples = rhiCtx->mainPassSampleCount();
1684 ps.viewCount = rhiCtx->mainPassViewCount();
1686 ps.flags.setFlag(QSSGRhiGraphicsPipelineState::Flag::BlendEnabled,
true);
1687 ps.flags.setFlag(QSSGRhiGraphicsPipelineState::Flag::DepthWriteEnabled,
false);
1689 shaderFeatures = data.getShaderFeatures();
1690 sortedTransparentObjects = data.getSortedTransparentRenderableObjects(*camera);
1692 if (method == QSSGRenderLayer::OITMethod::WeightedBlended) {
1693 ps.colorAttachmentCount = 2;
1695 rhiAccumTexture = data.getRenderResult(QSSGRenderResult::Key::AccumTexture);
1696 rhiRevealageTexture = data.getRenderResult(QSSGRenderResult::Key::RevealageTexture);
1698 rhiDepthTexture = data.getRenderResult(QSSGRenderResult::Key::DepthTextureMS);
1700 rhiDepthTexture = data.getRenderResult(QSSGRenderResult::Key::DepthTexture);
1701 if (!rhiDepthTexture->isValid())
1703 auto &oitrt = data.getOitRenderContext();
1704 if (!oitrt.oitRenderTarget || oitrt.oitRenderTarget->pixelSize() != data.layerPrepResult.textureDimensions()
1705 || rhiDepthTexture->texture != oitrt.oitRenderTarget->description().depthTexture()
1706 || ps.samples != oitrt.oitRenderTarget->sampleCount()) {
1707 if (oitrt.oitRenderTarget) {
1708 rhiAccumTexture->texture->destroy();
1709 rhiRevealageTexture->texture->destroy();
1710 oitrt.oitRenderTarget->destroy();
1711 oitrt.renderPassDescriptor->destroy();
1712 oitrt.oitRenderTarget =
nullptr;
1714 const QRhiTexture::Flags textureFlags = QRhiTexture::RenderTarget;
1715 if (ps.viewCount >= 2) {
1716 rhiAccumTexture->texture = rhi->newTextureArray(QRhiTexture::RGBA16F, ps.viewCount, data.layerPrepResult.textureDimensions(), ps.samples, textureFlags);
1717 rhiRevealageTexture->texture = rhi->newTextureArray(QRhiTexture::R16F, ps.viewCount, data.layerPrepResult.textureDimensions(), ps.samples, textureFlags);
1719 rhiAccumTexture->texture = rhi->newTexture(QRhiTexture::RGBA16F, data.layerPrepResult.textureDimensions(), ps.samples, textureFlags);
1720 rhiRevealageTexture->texture = rhi->newTexture(QRhiTexture::R16F, data.layerPrepResult.textureDimensions(), ps.samples, textureFlags);
1722 rhiAccumTexture->texture->create();
1723 rhiRevealageTexture->texture->create();
1725 QRhiTextureRenderTargetDescription desc;
1726 desc.setColorAttachments({{rhiAccumTexture->texture}, {rhiRevealageTexture->texture}});
1727 desc.setDepthTexture(rhiDepthTexture->texture);
1729 if (oitrt.oitRenderTarget ==
nullptr) {
1730 oitrt.oitRenderTarget = rhi->newTextureRenderTarget(desc, QRhiTextureRenderTarget::PreserveDepthStencilContents);
1731 oitrt.renderPassDescriptor = oitrt.oitRenderTarget->newCompatibleRenderPassDescriptor();
1732 oitrt.oitRenderTarget->setRenderPassDescriptor(oitrt.renderPassDescriptor);
1733 oitrt.oitRenderTarget->create();
1735 renderTarget = oitrt.oitRenderTarget;
1738 QSSGRhiContextPrivate *rhiCtxD = QSSGRhiContextPrivate::get(rhiCtx.get());
1739 const auto &shaderCache = renderer.contextInterface()->shaderCache();
1740 clearPipeline = shaderCache->getBuiltInRhiShaders().getRhiClearMRTShader();
1742 QSSGRhiShaderResourceBindingList bindings;
1743 QVector4D clearData[2];
1744 clearData[0] = QVector4D(0.0, 0.0, 0.0, 0.0);
1745 clearData[1] = QVector4D(1.0, 1.0, 1.0, 1.0);
1747 QSSGRhiDrawCallData &dcd(rhiCtxD->drawCallData({
this, clearPipeline.get(),
nullptr, 0 }));
1748 QRhiBuffer *&ubuf = dcd.ubuf;
1749 const int ubufSize =
sizeof(clearData);
1751 ubuf = rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, ubufSize);
1755 QRhiResourceUpdateBatch *rub = rhi->nextResourceUpdateBatch();
1756 rub->updateDynamicBuffer(ubuf, 0, ubufSize, &clearData);
1757 renderer.rhiQuadRenderer()->prepareQuad(rhiCtx.get(), rub);
1759 bindings.addUniformBuffer(0, QRhiShaderResourceBinding::FragmentStage, ubuf);
1761 clearSrb = rhiCtxD->srb(bindings);
1763 ps.targetBlend[0].srcAlpha = QRhiGraphicsPipeline::One;
1764 ps.targetBlend[0].srcColor = QRhiGraphicsPipeline::One;
1765 ps.targetBlend[0].dstAlpha = QRhiGraphicsPipeline::One;
1766 ps.targetBlend[0].dstColor = QRhiGraphicsPipeline::One;
1767 ps.targetBlend[1].srcAlpha = QRhiGraphicsPipeline::Zero;
1768 ps.targetBlend[1].srcColor = QRhiGraphicsPipeline::Zero;
1769 ps.targetBlend[1].dstAlpha = QRhiGraphicsPipeline::OneMinusSrcAlpha;
1770 ps.targetBlend[1].dstColor = QRhiGraphicsPipeline::OneMinusSrcAlpha;
1772 TransparentPass::prep(*ctx, data,
this, ps, shaderFeatures, oitrt.renderPassDescriptor, sortedTransparentObjects,
true);
1773 }
else if (method == QSSGRenderLayer::OITMethod::LinkedList) {
1775 rhiCtx->commandBuffer()->resourceUpdate(
this->rub);
1776 this->rub =
nullptr;
1780 ps.flags.setFlag(QSSGRhiGraphicsPipelineState::Flag::BlendEnabled,
true);
1781 ps.flags.setFlag(QSSGRhiGraphicsPipelineState::Flag::DepthWriteEnabled,
false);
1782 ps.targetBlend[0].srcAlpha = QRhiGraphicsPipeline::One;
1783 ps.targetBlend[0].srcColor = QRhiGraphicsPipeline::SrcAlpha;
1784 ps.targetBlend[0].dstAlpha = QRhiGraphicsPipeline::OneMinusSrcAlpha;
1785 ps.targetBlend[0].dstColor = QRhiGraphicsPipeline::OneMinusSrcAlpha;
1787 shaderFeatures = data.getShaderFeatures();
1788 sortedTransparentObjects = data.getSortedTransparentRenderableObjects(*camera);
1790#ifdef QSSG_OIT_USE_BUFFERS
1791 auto &oitCtx = data.getOitRenderContext();
1792 rhiABuffer = oitCtx.aBuffer;
1793 rhiAuxBuffer = oitCtx.auxBuffer;
1794 rhiCounterBuffer = oitCtx.counterBuffer;
1796 rhiABufferImage = data.getRenderResult(QSSGRenderResult::Key::ABufferImage);
1797 rhiAuxiliaryImage = data.getRenderResult(QSSGRenderResult::Key::AuxiliaryImage);
1798 rhiCounterImage = data.getRenderResult(QSSGRenderResult::Key::CounterImage);
1800 QSize dim = data.layerPrepResult.textureDimensions();
1801 dim.setWidth(dim.width() * ps.samples);
1802 dim.setHeight(dim.height() * ps.viewCount);
1803#ifdef QSSG_OIT_USE_BUFFERS
1804 if (!rhiAuxBuffer || rhiAuxBuffer->size() != (dim.width() * dim.height() * 4u) || currentNodeCount == 0 || linkedListRequiresResize(dim))
1806 if (!rhiAuxiliaryImage->texture || rhiAuxiliaryImage->texture->pixelSize() != dim || currentNodeCount == 0 || linkedListRequiresResize(dim))
1809 quint32 extraNodeCount = 0;
1810#ifdef QSSG_OIT_USE_BUFFERS
1811 if (rhiAuxBuffer && rhiAuxBuffer->size() != (dim.width() * dim.height() * 4u)) {
1812 if (rhiAuxBuffer->size() < (dim.width() * dim.height() * 4u))
1813 extraNodeCount = ensureFreeNodes((dim.width() * dim.height() * 4u) - rhiAuxBuffer->size(), 32u * 1024u);
1814 rhiAuxBuffer->destroy();
1815 rhiAuxBuffer =
nullptr;
1818 if (rhiABufferImage->texture) {
1819 const auto s = rhiAuxiliaryImage->texture->pixelSize();
1820 if (s.width() * s.height() < dim.width() * dim.height())
1821 extraNodeCount = ensureFreeNodes(dim.width() * dim.height() - s.width() * s.height(), 32u * 1024u);
1822 rhiABufferImage->texture->destroy();
1823 rhiAuxiliaryImage->texture->destroy();
1827 if (reportedNodeCount) {
1829 currentNodeCount = ensureFreeNodes(reportedNodeCount + extraNodeCount, dim.width() * dim.height() / 2);
1831 quint32 size = RenderHelpers::rhiCalculateABufferSize(data.layerPrepResult.textureDimensions(), 4 * ps.samples * ps.viewCount);
1832 currentNodeCount = ensureFreeNodes(size * size, 32u * 1024u);
1834 data.layer.oitNodeCount = currentNodeCount;
1836#ifdef QSSG_OIT_USE_BUFFERS
1837 if (rhiABuffer && currentNodeCount * 16 != rhiABuffer->size()) {
1838 rhiABuffer->destroy();
1839 rhiABuffer =
nullptr;
1842 rhiABuffer = rhi->newBuffer(QRhiBuffer::Static, QRhiBuffer::StorageBuffer, currentNodeCount * 16);
1843 rhiABuffer->create();
1845 if (!rhiAuxBuffer) {
1846 rhiAuxBuffer = rhi->newBuffer(QRhiBuffer::Static, QRhiBuffer::StorageBuffer, dim.width() * dim.height() * 4);
1847 rhiAuxBuffer->create();
1849 if (!rhiCounterBuffer) {
1850 rhiCounterBuffer = rhi->newBuffer(QRhiBuffer::Static, QRhiBuffer::StorageBuffer, 4);
1851 rhiCounterBuffer->create();
1852 oitCtx.counterBuffer = rhiCounterBuffer;
1854 oitCtx.aBuffer = rhiABuffer;
1855 oitCtx.auxBuffer = rhiAuxBuffer;
1857 quint32 sizeWithLayers = RenderHelpers::rhiCalculateABufferSize(currentNodeCount);
1858 const QRhiTexture::Flags textureFlags = QRhiTexture::UsedWithLoadStore;
1859 rhiABufferImage->texture = rhi->newTexture(QRhiTexture::RGBA32UI, QSize(sizeWithLayers, sizeWithLayers), 1, textureFlags);
1860 rhiABufferImage->texture->create();
1861 rhiAuxiliaryImage->texture = rhi->newTexture(QRhiTexture::R32UI, dim, 1, textureFlags);
1862 rhiAuxiliaryImage->texture->create();
1863 if (!rhiCounterImage->texture) {
1864 rhiCounterImage->texture = rhi->newTexture(QRhiTexture::R32UI, QSize(1, 1), 1, textureFlags | QRhiTexture::UsedAsTransferSource);
1865 rhiCounterImage->texture->create();
1867 auto &oitrt = data.getOitRenderContext();
1868 readbackImage = rhi->newTexture(QRhiTexture::R32UI, QSize(1, 1), 1, QRhiTexture::UsedAsTransferSource);
1874 QRhiResourceUpdateBatch *rub = rhiCtx->rhi()->nextResourceUpdateBatch();
1876 QSSGRhiContextPrivate *rhiCtxD = QSSGRhiContextPrivate::get(rhiCtx.get());
1877 const auto &shaderCache = renderer.contextInterface()->shaderCache();
1878#ifdef QSSG_OIT_USE_BUFFERS
1879 clearPipeline = shaderCache->getBuiltInRhiShaders().getRhiClearBufferShader();
1881 clearPipeline = shaderCache->getBuiltInRhiShaders().getRhiClearImageShader();
1883 QSSGRhiShaderResourceBindingList bindings;
1884 quint32 clearImageData[8] = {0};
1886 QSSGRhiDrawCallData &dcd(rhiCtxD->drawCallData({
this, clearPipeline.get(),
nullptr, 0 }));
1887 QRhiBuffer *&ubuf = dcd.ubuf;
1888 const int ubufSize =
sizeof(clearImageData);
1890 ubuf = rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, ubufSize);
1894 clearImageData[4] = data.layerPrepResult.textureDimensions().width();
1895 clearImageData[5] = data.layerPrepResult.textureDimensions().height();
1896 clearImageData[6] = ps.samples;
1897 clearImageData[7] = ps.viewCount;
1899 rub->updateDynamicBuffer(ubuf, 0, ubufSize, clearImageData);
1901#ifdef QSSG_OIT_USE_BUFFERS
1902 rub->uploadStaticBuffer(rhiCounterBuffer, 0, 4, &zero);
1904 rub->uploadTexture(rhiCounterImage->texture, {{0, 0, {&zero, 4}}});
1907 bindings.addUniformBuffer(0, QRhiShaderResourceBinding::FragmentStage, ubuf);
1908#ifdef QSSG_OIT_USE_BUFFERS
1909 bindings.addStorageBuffer(1, QRhiShaderResourceBinding::FragmentStage, rhiAuxBuffer);
1911 bindings.addImageStore(1, QRhiShaderResourceBinding::FragmentStage, rhiAuxiliaryImage->texture, 0);
1914 clearSrb = rhiCtxD->srb(bindings);
1916 renderer.rhiQuadRenderer()->prepareQuad(rhiCtx.get(), rub);
1918 TransparentPass::prep(*ctx, data,
this, ps, shaderFeatures, rhiCtx->mainRenderPassDescriptor(), sortedTransparentObjects,
true);
1924 auto *ctx = renderer.contextInterface();
1925 const auto &rhiCtx = ctx->rhiContext();
1926 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(),
return);
1927 QRhiCommandBuffer *cb = rhiCtx->commandBuffer();
1929 if (method == QSSGRenderLayer::OITMethod::WeightedBlended) {
1930 if (Q_LIKELY(renderTarget)) {
1931 cb->beginPass(renderTarget, Qt::black, {});
1933 QRhiShaderResourceBindings *srb = clearSrb;
1935 ps.flags.setFlag(QSSGRhiGraphicsPipelineState::Flag::BlendEnabled,
false);
1936 QSSGRhiGraphicsPipelineStatePrivate::setShaderPipeline(ps, clearPipeline.get());
1937 renderer.rhiQuadRenderer()->recordRenderQuad(rhiCtx.get(), &ps, srb, renderTarget->renderPassDescriptor(), {});
1938 ps.flags.setFlag(QSSGRhiGraphicsPipelineState::Flag::BlendEnabled,
true);
1940 cb->debugMarkBegin(QByteArrayLiteral(
"Quick3D render order-independent alpha"));
1941 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderPass);
1942 Q_TRACE(QSSG_renderPass_entry, QStringLiteral(
"Quick3D render order-independent alpha"));
1943 ps.flags.setFlag(QSSGRhiGraphicsPipelineState::Flag::DepthTestEnabled,
true);
1944 ps.flags.setFlag(QSSGRhiGraphicsPipelineState::Flag::DepthWriteEnabled,
false);
1945 TransparentPass::render(*ctx, ps, sortedTransparentObjects);
1947 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral(
"transparent_order_independent_pass"));
1948 Q_TRACE(QSSG_renderPass_exit);
1952 }
else if (method == QSSGRenderLayer::OITMethod::LinkedList) {
1953 cb->debugMarkBegin(QByteArrayLiteral(
"Quick3D render alpha"));
1954 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderPass);
1955 Q_TRACE(QSSG_renderPass_entry, QStringLiteral(
"Quick3D render alpha"));
1957 QRhiShaderResourceBindings *srb = clearSrb;
1959 ps.flags.setFlag(QSSGRhiGraphicsPipelineState::Flag::BlendEnabled,
true);
1960 QSSGRhiGraphicsPipelineStatePrivate::setShaderPipeline(ps, clearPipeline.get());
1961 renderer.rhiQuadRenderer()->recordRenderQuad(rhiCtx.get(), &ps, srb, rhiCtx->mainRenderPassDescriptor(), {});
1963 TransparentPass::render(*ctx, ps, sortedTransparentObjects);
1964#ifdef QSSG_OIT_USE_BUFFERS
1965 QRhiResourceUpdateBatch *rub = rhiCtx->rhi()->nextResourceUpdateBatch();
1966 QRhiReadbackResult *result =
nullptr;
1967 if (results.size() > 1) {
1968 result = results.takeLast();
1969 result->pixelSize = {};
1971 result->format = QRhiTexture::UnknownFormat;
1973 result =
new QRhiReadbackResult();
1975 const auto completedFunc = [
this, result](){
1977 const quint32 *d =
reinterpret_cast<
const quint32 *>(result->data.constData());
1978 quint32 nodeCount = *d;
1980 this->reportedNodeCount = ensureFreeNodes(nodeCount, 32u * 1024u);
1981 this->results.append(result);
1984 result->completed = completedFunc;
1985 rub->readBackBuffer(rhiCounterBuffer, 0, 4, result);
1988 QRhiResourceUpdateBatch *rub = rhiCtx->rhi()->nextResourceUpdateBatch();
1990 QRhiReadbackDescription rbdesc;
1992 QRhiReadbackResult *result =
nullptr;
1993 if (results.size() > 1) {
1994 result = results.takeLast();
1995 result->pixelSize = {};
1997 result->format = QRhiTexture::UnknownFormat;
1999 result =
new QRhiReadbackResult();
2001 const auto completedFunc = [
this, result](){
2003 const quint32 *d =
reinterpret_cast<
const quint32 *>(result->data.constData());
2004 quint32 nodeCount = *d;
2006 this->reportedNodeCount = ensureFreeNodes(nodeCount, 32u * 1024u);
2007 this->results.append(result);
2010 result->completed = completedFunc;
2011 rub->readBackTexture(rbdesc, result);
2015 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral(
"transparent_order_independent_pass"));
2016 Q_TRACE(QSSG_renderPass_exit);
2104 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
2105 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(),
return);
2106 QRhiCommandBuffer *cb = rhiCtx->commandBuffer();
2108 QSSGRhiContextPrivate *rhiCtxD = QSSGRhiContextPrivate::get(rhiCtx.get());
2110 if (!rhiAccumTexture->texture || !rhiRevealageTexture->texture)
2113 if (method == QSSGRenderLayer::OITMethod::WeightedBlended) {
2114 QSSGRhiShaderResourceBindingList bindings;
2116 QRhiSampler *sampler = rhiCtx->sampler({ QRhiSampler::Nearest,
2117 QRhiSampler::Nearest,
2119 QRhiSampler::ClampToEdge,
2120 QRhiSampler::ClampToEdge,
2121 QRhiSampler::ClampToEdge });
2122 bindings.addTexture(1, QRhiShaderResourceBinding::FragmentStage, rhiAccumTexture->texture, sampler);
2123 bindings.addTexture(2, QRhiShaderResourceBinding::FragmentStage, rhiRevealageTexture->texture, sampler);
2125 compositeSrb = rhiCtxD->srb(bindings);
2127 QRhiShaderResourceBindings *srb = compositeSrb;
2130 cb->debugMarkBegin(QByteArrayLiteral(
"Quick3D revealage"));
2131 QSSGRhiGraphicsPipelineStatePrivate::setShaderPipeline(ps, compositeShaderPipeline.get());
2132 ps.flags.setFlag(QSSGRhiGraphicsPipelineState::Flag::BlendEnabled,
true);
2133 renderer.rhiQuadRenderer()->recordRenderQuad(rhiCtx.get(), &ps, srb, rhiCtx->mainRenderPassDescriptor(),
2134 { QSSGRhiQuadRenderer::UvCoords | QSSGRhiQuadRenderer::DepthTest | QSSGRhiQuadRenderer::PremulBlend});
2135 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral(
"revealage"));
2137 }
else if (method == QSSGRenderLayer::OITMethod::LinkedList) {
2138 QSSGRhiShaderResourceBindingList bindings;
2140 QSSGRhiContextPrivate *rhiCtxD = QSSGRhiContextPrivate::get(rhiCtx.get());
2141 QSSGRhiDrawCallData &dcd(rhiCtxD->drawCallData({
this,
nullptr,
nullptr, 0 }));
2142 QRhiBuffer *&ubuf = dcd.ubuf;
2144 bindings.addUniformBuffer(0, QRhiShaderResourceBinding::FragmentStage, ubuf);
2145#ifdef QSSG_OIT_USE_BUFFERS
2146 bindings.addStorageBuffer(1, QRhiShaderResourceBinding::FragmentStage, rhiABuffer);
2147 bindings.addStorageBuffer(2, QRhiShaderResourceBinding::FragmentStage, rhiAuxBuffer);
2149 bindings.addImageLoad(1, QRhiShaderResourceBinding::FragmentStage, rhiABufferImage->texture, 0);
2150 bindings.addImageLoad(2, QRhiShaderResourceBinding::FragmentStage, rhiAuxiliaryImage->texture, 0);
2153 compositeSrb = rhiCtxD->srb(bindings);
2155 QRhiShaderResourceBindings *srb = compositeSrb;
2158 cb->debugMarkBegin(QByteArrayLiteral(
"Quick3D oit-composite"));
2159 QSSGRhiGraphicsPipelineStatePrivate::setShaderPipeline(ps, compositeShaderPipeline.get());
2160 ps.flags.setFlag(QSSGRhiGraphicsPipelineState::Flag::BlendEnabled,
true);
2161 renderer.rhiQuadRenderer()->recordRenderQuad(rhiCtx.get(), &ps, srb, rhiCtx->mainRenderPassDescriptor(),
2162 { QSSGRhiQuadRenderer::UvCoords | QSSGRhiQuadRenderer::DepthTest | QSSGRhiQuadRenderer::PremulBlend});
2163 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral(
"oit-composite"));
2261 QSSGRenderUserPass *passNode,
2262 std::vector<UserPassData> &outData,
2263 QSSGRhiRenderableTextureV2Ptr renderableTexture)
2267 const bool isTopLevelPass = (renderableTexture ==
nullptr);
2269 QSSGRenderCamera *camera = data.renderedCameras[0];
2270 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
2272 const QSize targetSize = data.layerPrepResult.textureDimensions();
2274 static const auto needsRebuild = [](QRhiTexture *texture,
const QSize &size, QRhiTexture::Format format) {
2275 return !texture || texture->pixelSize() != size || texture->format() != format;
2278 qCDebug(lcUserRenderPass,
"renderPrep in UserRenderPass");
2280 const QSSGResourceId currentPassId = QSSGRenderGraphObjectUtils::getResourceId(*passNode);
2281 if (visitedPasses.find(currentPassId) != visitedPasses.end()) {
2282 qWarning(
"UserRenderPass: Circular dependency detected in SubRenderPass chain. Ignoring pass.");
2287 if (visitedPasses.size() >= MAX_SUBPASS_DEPTH) {
2288 qWarning(
"UserRenderPass: Maximum SubRenderPass nesting depth (%zu) exceeded. Ignoring pass.", MAX_SUBPASS_DEPTH);
2292 visitedPasses.insert(currentPassId);
2295 currentPassData.clearColor = passNode->clearColor;
2296 currentPassData.depthStencilClearValue = passNode->depthStencilClearValue;
2298 renderableTexture = currentPassData.renderableTexture = data.requestUserRenderPassManager()->getOrCreateRenderableTexture(*passNode);
2300 currentPassData.renderableTexture = renderableTexture;
2302 QSSGRenderableObjectList &renderables = currentPassData.renderables;
2303 QSSGRhiGraphicsPipelineState &ps = currentPassData.ps;
2304 const auto &renderTarget = currentPassData.renderableTexture;
2307 ps = data.getPipelineState();
2309 bool renderablesFiltered =
false;
2311 bool needsDepthStencilRenderBuffer =
false;
2312 QSSGAllocateTexturePtr depthTextureAllocCommand;
2314 QVarLengthArray<QSSGColorAttachment *, 16> colorAttachments;
2315 QVarLengthArray<QSSGResourceId, 4> subPassIds;
2318 for (
const QSSGCommand *theCommand : std::as_const(passNode->commands)) {
2321 qCDebug(lcUserRenderPass) <<
"Exec. command: >" << theCommand->typeAsString() <<
"--" << theCommand->debugString();
2323 switch (theCommand->m_type) {
2324 case CommandType::ColorAttachment:
2326 const QSSGColorAttachment *colorAttachCmd =
static_cast<
const QSSGColorAttachment *>(theCommand);
2327 colorAttachments.push_back(
const_cast<QSSGColorAttachment *>(colorAttachCmd));
2330 case CommandType::DepthTextureAttachment:
2332 QSSG_ASSERT(depthTextureAllocCommand ==
nullptr,
break);
2333 const QSSGDepthTextureAttachment *depthAttachCmd =
static_cast<
const QSSGDepthTextureAttachment *>(theCommand);
2334 needsDepthStencilRenderBuffer =
false;
2335 depthTextureAllocCommand = depthAttachCmd->m_textureCmd;
2338 case CommandType::AddShaderDefine:
2340 const auto *defineCmd =
static_cast<
const QSSGAddShaderDefine *>(theCommand);
2341 const auto &defineName = defineCmd->m_name;
2342 if (defineName.size() > 0) {
2343 QByteArray value = QByteArray::number(defineCmd->m_value);
2344 currentPassData.shaderDefines.push_back({ defineName, value });
2348 case CommandType::RenderablesFilter:
2350 auto filterCommand =
static_cast<
const QSSGRenderablesFilterCommand *>(theCommand);
2354 enum RenderableType : quint8 {
2360 if (filterCommand->renderableTypes & RenderableType::Opaque)
2361 renderables = data.getSortedOpaqueRenderableObjects(*camera, 0, filterCommand->layerMask);
2362 if (filterCommand->renderableTypes & RenderableType::Transparent)
2363 renderables += data.getSortedTransparentRenderableObjects(*camera, 0, filterCommand->layerMask);
2367 renderablesFiltered =
true;
2371 case CommandType::PipelineStateOverride:
2373 auto pipelineCommand =
static_cast<
const QSSGPipelineStateOverrideCommand *>(theCommand);
2374 if (pipelineCommand->m_depthTestEnabled)
2375 ps.flags.setFlag(QSSGRhiGraphicsPipelineState::Flag::DepthTestEnabled, *pipelineCommand->m_depthTestEnabled);
2376 if (pipelineCommand->m_depthWriteEnabled)
2377 ps.flags.setFlag(QSSGRhiGraphicsPipelineState::Flag::DepthWriteEnabled, *pipelineCommand->m_depthWriteEnabled);
2378 if (pipelineCommand->m_blendEnabled)
2379 ps.flags.setFlag(QSSGRhiGraphicsPipelineState::Flag::BlendEnabled, *pipelineCommand->m_blendEnabled);
2380 if (pipelineCommand->m_usesStencilReference)
2381 ps.flags.setFlag(QSSGRhiGraphicsPipelineState::Flag::UsesStencilRef, *pipelineCommand->m_usesStencilReference);
2382 if (pipelineCommand->m_usesScissor)
2383 ps.flags.setFlag(QSSGRhiGraphicsPipelineState::Flag::UsesScissor, *pipelineCommand->m_usesScissor);
2384 if (pipelineCommand->m_depthFunction)
2385 ps.depthFunc = *pipelineCommand->m_depthFunction;
2386 if (pipelineCommand->m_cullMode) {
2387 ps.cullMode = *pipelineCommand->m_cullMode;
2388 ps.userSetCullMode =
true;
2390 if (pipelineCommand->m_polygonMode)
2391 ps.polygonMode = *pipelineCommand->m_polygonMode;
2392 if (pipelineCommand->m_stencilOpFrontState)
2393 ps.stencilOpFrontState = *pipelineCommand->m_stencilOpFrontState;
2394 if (pipelineCommand->m_stencilWriteMask)
2395 ps.stencilWriteMask = *pipelineCommand->m_stencilWriteMask;
2396 if (pipelineCommand->m_stencilReference)
2397 ps.stencilRef = *pipelineCommand->m_stencilReference;
2398 if (pipelineCommand->m_viewport)
2399 ps.viewport = *pipelineCommand->m_viewport;
2400 if (pipelineCommand->m_scissor)
2401 ps.scissor = *pipelineCommand->m_scissor;
2402 if (pipelineCommand->m_targetBlend0)
2403 ps.targetBlend[0] = *pipelineCommand->m_targetBlend0;
2404 if (pipelineCommand->m_targetBlend1)
2405 ps.targetBlend[1] = *pipelineCommand->m_targetBlend1;
2406 if (pipelineCommand->m_targetBlend2)
2407 ps.targetBlend[2] = *pipelineCommand->m_targetBlend2;
2408 if (pipelineCommand->m_targetBlend3)
2409 ps.targetBlend[3] = *pipelineCommand->m_targetBlend3;
2410 if (pipelineCommand->m_targetBlend4)
2411 ps.targetBlend[4] = *pipelineCommand->m_targetBlend4;
2412 if (pipelineCommand->m_targetBlend5)
2413 ps.targetBlend[5] = *pipelineCommand->m_targetBlend5;
2414 if (pipelineCommand->m_targetBlend6)
2415 ps.targetBlend[6] = *pipelineCommand->m_targetBlend6;
2416 if (pipelineCommand->m_targetBlend7)
2417 ps.targetBlend[7] = *pipelineCommand->m_targetBlend7;
2420 case CommandType::DepthStencilAttachment:
2422 QSSG_ASSERT(depthTextureAllocCommand ==
nullptr,
break);
2423 needsDepthStencilRenderBuffer =
true;
2425 case CommandType::SubRenderPass:
2427 auto subPassCommand =
static_cast<
const QSSGSubRenderPass *>(theCommand);
2428 if (subPassCommand && subPassCommand->m_userPassId != QSSGResourceId::Invalid)
2429 subPassIds.append(subPassCommand->m_userPassId);
2433 qWarning() <<
"Effect command" << theCommand->typeAsString() <<
"not implemented";
2438 if (colorAttachments.size() > 4) {
2439 colorAttachments.resize(4);
2440 qWarning() <<
"UserRenderPass supports up to 4 color attachments only.";
2445 if (isTopLevelPass) {
2447 bool needsBuild = !renderTarget->isValid();
2449 const qsizetype oldAttachmentCount = renderTarget->colorAttachmentCount();
2451 if (oldAttachmentCount != colorAttachments.size())
2458 if (renderTarget->getRenderTarget() && renderTarget->getRenderTarget()->flags() != passNode->renderTargetFlags)
2464 for (
int i = 0; i != oldAttachmentCount; ++i) {
2465 const auto &colorAttachment = colorAttachments.at(i);
2466 QSSG_ASSERT(colorAttachment !=
nullptr,
continue);
2467 const auto expectedFormat = QSSGBufferManager::toRhiFormat(colorAttachment->format());
2468 const auto &texture = renderTarget->getColorTexture(i);
2469 needsBuild = needsBuild || needsRebuild(&(*texture->texture()), targetSize, expectedFormat);
2473 if (needsDepthStencilRenderBuffer != (renderTarget->getDepthStencil() !=
nullptr))
2477 if (depthTextureAllocCommand) {
2478 const auto format = QSSGBufferManager::toRhiFormat(depthTextureAllocCommand->format());
2479 const auto &depthTextureWrapper = renderTarget->getDepthTexture();
2480 needsBuild = depthTextureWrapper ==
nullptr;
2481 needsBuild = needsBuild || needsRebuild(&(*depthTextureWrapper->texture()), targetSize, format);
2483 if (renderTarget->getDepthTexture() !=
nullptr)
2489 const auto &rt = renderTarget->getRenderTarget();
2490 if (rt && rt->flags() != passNode->renderTargetFlags)
2496 renderTarget->reset();
2498 QRhiTextureRenderTargetDescription rtDesc;
2501 const qsizetype colorAttachmentCount = qMax<qsizetype>(colorAttachments.size(), 1);
2503 bool createSucceeded =
true;
2504 bool colorAllocatorsNeedsUpdate =
false;
2508 QVarLengthArray<QRhiTexture *, 4> textures;
2509 for (qsizetype i = 0; i < colorAttachmentCount && createSucceeded ; ++i) {
2510 const auto &colorAttCmd = colorAttachments.at(i);
2511 const auto &name = colorAttCmd->m_name;
2512 const auto format = QSSGBufferManager::toRhiFormat(colorAttCmd->format());
2513 const auto &allocateTexCmd = colorAttCmd->m_textureCmd;
2514 if (allocateTexCmd->texture() && !needsRebuild(&(*allocateTexCmd->texture()->texture()), targetSize, format)) {
2517 textures.push_back(allocateTexCmd->texture()->texture().get());
2519 auto *tex = rhiCtx->rhi()->newTexture(format, targetSize, ps.samples, QRhiTexture::RenderTarget);
2521 createSucceeded = createSucceeded && tex->create();
2522 textures.push_back(tex);
2526 colorAllocatorsNeedsUpdate =
true;
2530 rtDesc.setColorAttachments(textures.cbegin(), textures.cend());
2533 if (needsDepthStencilRenderBuffer) {
2534 auto renderBuffer = rhiCtx->rhi()->newRenderBuffer(QRhiRenderBuffer::DepthStencil, targetSize, ps.samples);
2535 if (renderBuffer->create())
2536 rtDesc.setDepthStencilBuffer(renderBuffer);
2537 }
else if (depthTextureAllocCommand) {
2538 const auto format = QSSGBufferManager::toRhiFormat(depthTextureAllocCommand->format());
2539 if (depthTextureAllocCommand->texture() && !needsRebuild(&(*depthTextureAllocCommand->texture()->texture()), targetSize, format)) {
2540 rtDesc.setDepthTexture(depthTextureAllocCommand->texture()->texture().get());
2543 QRhiTexture *depthTex = rhiCtx->rhi()->newTexture(format, targetSize, ps.samples, QRhiTexture::RenderTarget);
2544 if (depthTex->create())
2545 rtDesc.setDepthTexture(depthTex);
2549 if (createSucceeded) {
2551 renderTarget->setDescription(rhiCtx->rhi(),
std::move(rtDesc), passNode->renderTargetFlags);
2554 if (colorAllocatorsNeedsUpdate) {
2555 for (qsizetype i = 0; i < colorAttachmentCount; ++i) {
2556 const auto &colorAttCmd = colorAttachments.at(i);
2557 const auto &allocateTexCmd = colorAttCmd->m_textureCmd;
2558 allocateTexCmd->setTexture(renderTarget->getColorTexture(i));
2562 if (depthTextureAllocCommand)
2563 depthTextureAllocCommand->setTexture(renderTarget->getDepthTexture());
2566 renderTarget->resetRenderTarget();
2567 qWarning() <<
"Failed to create textures for UserRenderPass";
2573 Q_ASSERT(renderTarget->isValid());
2575 ps.colorAttachmentCount =
int(renderTarget->colorAttachmentCount());
2578 for (
const auto &subPassId : std::as_const(subPassIds)) {
2579 QSSGRenderUserPass *userPassNode = QSSGRenderGraphObjectUtils::getResource<QSSGRenderUserPass>(subPassId);
2580 QSSG_ASSERT(userPassNode && userPassNode->type == QSSGRenderGraphObject::Type::RenderPass,
continue);
2581 prepareSubPass(renderer, data, userPassNode, currentPassData.subPassData, currentPassData.renderableTexture);
2584 if (passNode->passMode == QSSGRenderUserPass::PassModes::UserPass) {
2586 if (!renderablesFiltered && renderables.isEmpty())
2587 renderables = data.getSortedOpaqueRenderableObjects(*camera);
2589 if (passNode->materialMode == QSSGRenderUserPass::MaterialModes::AugmentMaterial) {
2593 QSSG_ASSERT(shaderAugmentation.outputs.size() == 0, shaderAugmentation.outputs.clear());
2594 shaderAugmentation.defines =
std::move(currentPassData.shaderDefines);
2596 for (
int i = 0, end = colorAttachments.size(); i < end; ++i) {
2597 const auto &colorAttCmd = colorAttachments.at(i);
2598 const auto &name = colorAttCmd->m_name;
2599 if (name.size() > 0)
2600 shaderAugmentation.outputs.push_back(name);
2602 shaderAugmentation.outputs.push_back(getDefaultOutputName(size_t(i)));
2605 QSSGShaderFeatures shaderFeatures = data.getShaderFeatures();
2606 shaderFeatures.disableTonemapping();
2608 currentPassData.index = RenderHelpers::rhiPrepareAugmentedUserPass(&(*rhiCtx),
this, ps, renderTarget->getRenderPassDescriptor().get(), shaderAugmentation, data, renderables, shaderFeatures);
2609 }
else if (passNode->materialMode == QSSGRenderUserPass::MaterialModes::OverrideMaterial) {
2611 QSSGShaderFeatures shaderFeatures = data.getShaderFeatures();
2612 shaderFeatures.disableTonemapping();
2614 currentPassData.index = RenderHelpers::rhiPrepareOverrideMaterialUserPass(&(*rhiCtx),
this, ps, renderTarget->getRenderPassDescriptor().get(), passNode->overrideMaterial, data, renderables, shaderFeatures);
2618 QSSGShaderFeatures shaderFeatures = data.getShaderFeatures();
2619 shaderFeatures.disableTonemapping();
2620 currentPassData.index = RenderHelpers::rhiPrepareOriginalMaterialUserPass(&(*rhiCtx),
this, ps, renderTarget->getRenderPassDescriptor().get(), data, renderables, shaderFeatures);
2622 outData.push_back(currentPassData);
2625 if (passNode->passMode == QSSGRenderUserPass::PassModes::SkyboxPass) {
2626 if (rhiCtx->rhi()->isFeatureSupported(QRhi::TexelFetch)) {
2627 if (data.layer.background == QSSGRenderLayer::Background::SkyBoxCubeMap && data.layer.skyBoxCubeMap) {
2628 if (!currentPassData.skyboxCubeMapPass)
2631 currentPassData.skyboxCubeMapPass->skipTonemapping =
true;
2632 currentPassData.skyboxCubeMapPass->renderPrep(renderer, data);
2633 currentPassData.skyboxCubeMapPass->ps.samples = ps.samples;
2634 currentPassData.skyboxCubeMapPass->rpDesc = renderTarget->getRenderPassDescriptor().get();
2636 currentPassData.skyboxPass =
std::nullopt;
2637 }
else if ((data.layer.background == QSSGRenderLayer::Background::SkyBox && data.layer.lightProbe)
2638 || (data.layer.background == QSSGRenderLayer::Background::SkyMaterial && data.layer.skyMaterial)) {
2639 if (!currentPassData.skyboxPass)
2642 currentPassData.skyboxPass->skipTonemapping =
true;
2643 currentPassData.skyboxPass->renderPrep(renderer, data);
2644 currentPassData.skyboxPass->ps.samples = ps.samples;
2645 currentPassData.skyboxPass->rpDesc = renderTarget->getRenderPassDescriptor().get();
2647 currentPassData.skyboxCubeMapPass =
std::nullopt;
2649 outData.push_back(currentPassData);
2651 }
else if (passNode->passMode == QSSGRenderUserPass::PassModes::Item2DPass) {
2652 if (!currentPassData.item2DPass)
2654 const bool hasItem2Ds = (data.item2DsView.size() > 0);
2657 QSSGRhiContextPrivate *rhiCtxD = QSSGRhiContextPrivate::get(renderer.contextInterface()->rhiContext().get());
2658 QRhiRenderTarget *prevRenderTarget = rhiCtx->renderTarget();
2659 rhiCtxD->setRenderTarget(renderTarget->getRenderTarget().get());
2660 currentPassData.item2DPass->renderPrep(renderer, data);
2662 rhiCtxD->setRenderTarget(prevRenderTarget);
2663 outData.push_back(currentPassData);