diff options
author | Antti Määttä <antti.maatta@qt.io> | 2023-08-14 13:21:07 +0300 |
---|---|---|
committer | Antti Määttä <antti.maatta@qt.io> | 2023-09-01 15:02:30 +0300 |
commit | 2b4ec2230eb21c277d82b80a729f1c8a5e2aee99 (patch) | |
tree | d60072dd9dac9cdcaecc3076a052332b8301db44 | |
parent | dfba2273014019a8153889d5b91ed7de7758d9f2 (diff) |
Layer caching for stereoscopic rendering doesn't work, because
1) the layer has only one texture for the left and right eyes and
it renders both eyes with the same texture thereby overwriting
the left eye.
2) the stereoscopic cameras are always dirty causing it to always render.
This patch adds second layer texture allowing the caching of both eyes
and also fixes the dirty camera problem by using the main camera to
calculate the camera dirty flags and stores them for the right eye so
that it also renders when left eye was dirty.
Task-number: QT3DS-4239
Change-Id: Ice46bb4828418eca628abcbb7bb6d21aacf48028
Reviewed-by: Tomi Korpipää <tomi.korpipaa@qt.io>
Reviewed-by: Janne Koskinen <janne.p.koskinen@qt.io>
4 files changed, 66 insertions, 51 deletions
diff --git a/src/runtimerender/rendererimpl/Qt3DSRendererImpl.cpp b/src/runtimerender/rendererimpl/Qt3DSRendererImpl.cpp index 9728f40..b39cc91 100644 --- a/src/runtimerender/rendererimpl/Qt3DSRendererImpl.cpp +++ b/src/runtimerender/rendererimpl/Qt3DSRendererImpl.cpp @@ -972,13 +972,13 @@ namespace render { uint Qt3DSRendererImpl::getLayerTextureId(SLayer &layer, const SRenderInstanceId id) { SLayerRenderData *data = GetOrCreateLayerRenderDataForNode(layer, id); - if (data->m_LayerCachedTexture) { + if (data->m_LayerCachedTexture[data->getCameraIndex()]) { return static_cast<uint>(reinterpret_cast<size_t>( - data->m_LayerCachedTexture->GetTextureObjectHandle())); + data->m_LayerCachedTexture[data->getCameraIndex()]->GetTextureObjectHandle())); } - if (data->m_LayerTexture) { + if (data->m_LayerTexture[data->getCameraIndex()]) { return static_cast<uint>(reinterpret_cast<size_t>( - data->m_LayerTexture->GetTextureObjectHandle())); + data->m_LayerTexture[data->getCameraIndex()]->GetTextureObjectHandle())); } return 0; } @@ -1008,10 +1008,10 @@ namespace render { { SLayerRenderData *theData = GetOrCreateLayerRenderDataForNode(inLayer, id); - if (theData->m_LayerCachedTexture) - return theData->m_LayerCachedTexture->GetTextureDetails(); - if (theData->m_LayerTexture) - return theData->m_LayerTexture->GetTextureDetails(); + if (theData->m_LayerCachedTexture[theData->getCameraIndex()]) + return theData->m_LayerCachedTexture[theData->getCameraIndex()]->GetTextureDetails(); + if (theData->m_LayerTexture[theData->getCameraIndex()]) + return theData->m_LayerTexture[theData->getCameraIndex()]->GetTextureDetails(); return {}; } diff --git a/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.cpp b/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.cpp index 803dda9..7348fb2 100644 --- a/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.cpp +++ b/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.cpp @@ -77,7 +77,8 @@ namespace render { SLayerRenderData::SLayerRenderData(SLayer &inLayer, Qt3DSRendererImpl &inRenderer) : SLayerRenderPreparationData(inLayer, inRenderer) - , m_LayerTexture(inRenderer.GetQt3DSContext().GetResourceManager()) + , m_LayerTexture{inRenderer.GetQt3DSContext().GetResourceManager(), + inRenderer.GetQt3DSContext().GetResourceManager()} , m_TemporalAATexture{inRenderer.GetQt3DSContext().GetResourceManager(), inRenderer.GetQt3DSContext().GetResourceManager()} , m_LayerDepthTexture(inRenderer.GetQt3DSContext().GetResourceManager()) @@ -87,7 +88,7 @@ namespace render { , m_LayerMultisampleTexture(inRenderer.GetQt3DSContext().GetResourceManager()) , m_LayerMultisamplePrepassDepthTexture(inRenderer.GetQt3DSContext().GetResourceManager()) , m_LayerMultisampleWidgetTexture(inRenderer.GetQt3DSContext().GetResourceManager()) - , m_LayerCachedTexture(NULL) + , m_LayerCachedTexture{NULL, NULL} , m_AdvancedBlendDrawTexture(NULL) , m_AdvancedBlendBlendTexture(NULL) , m_AdvancedModeDrawFB(NULL) @@ -105,8 +106,10 @@ namespace render { SLayerRenderData::~SLayerRenderData() { IResourceManager &theResourceManager(m_Renderer.GetQt3DSContext().GetResourceManager()); - if (m_LayerCachedTexture && m_LayerCachedTexture != m_LayerTexture) - theResourceManager.Release(*m_LayerCachedTexture); + if (m_LayerCachedTexture[0] && m_LayerCachedTexture[0] != m_LayerTexture[0]) + theResourceManager.Release(*m_LayerCachedTexture[0]); + if (m_LayerCachedTexture[1] && m_LayerCachedTexture[1] != m_LayerTexture[1]) + theResourceManager.Release(*m_LayerCachedTexture[1]); if (m_AdvancedModeDrawFB) { m_AdvancedModeDrawFB->release(); m_AdvancedModeDrawFB = NULL; @@ -133,13 +136,13 @@ namespace render { } // Get rid of the layer texture if we aren't rendering to texture this frame. - if (m_LayerTexture && !thePrepResult.m_Flags.ShouldRenderToTexture()) { - if (m_LayerCachedTexture && m_LayerCachedTexture != m_LayerTexture) { - theResourceManager.Release(*m_LayerCachedTexture); - m_LayerCachedTexture = NULL; + if (m_LayerTexture[getCameraIndex()] && !thePrepResult.m_Flags.ShouldRenderToTexture()) { + if (m_LayerCachedTexture[getCameraIndex()] && m_LayerCachedTexture[getCameraIndex()] != m_LayerTexture[getCameraIndex()]) { + theResourceManager.Release(*m_LayerCachedTexture[getCameraIndex()]); + m_LayerCachedTexture[getCameraIndex()] = NULL; } - m_LayerTexture.ReleaseTexture(); + m_LayerTexture[getCameraIndex()].ReleaseTexture(); m_LayerDepthTexture.ReleaseTexture(); m_LayerWidgetTexture.ReleaseTexture(); m_LayerSsaoTexture.ReleaseTexture(); @@ -162,7 +165,7 @@ namespace render { // Clean up the texture cache if layer dimensions changed if (inViewportDimensions.width() != m_previousDimensions.width() || inViewportDimensions.height() != m_previousDimensions.height()) { - m_LayerTexture.ReleaseTexture(); + m_LayerTexture[getCameraIndex()].ReleaseTexture(); m_LayerDepthTexture.ReleaseTexture(); m_LayerSsaoTexture.ReleaseTexture(); m_LayerWidgetTexture.ReleaseTexture(); @@ -184,6 +187,10 @@ namespace render { } bool isProgressiveAABlendPass = m_ProgressiveAAPassIndex && m_ProgressiveAAPassIndex < thePrepResult.m_MaxAAPassIndex; + // Save left eye flags for later + if (getCameraIndex() == 0) + m_LeftFlags = SLayerRenderPreparationResultFlags(thePrepResult.m_Flags); + return needsRender || isProgressiveAABlendPass; } @@ -1352,7 +1359,7 @@ void SLayerRenderData::RunRenderPass(TRenderRenderableFunction inRenderFn, theRenderContext.SetDepthTestEnabled(false); theRenderContext.SetDepthWriteEnabled(false); } - BlendAdvancedEquationSwFallback(m_AdvancedBlendDrawTexture, m_LayerTexture, advancedMode); + BlendAdvancedEquationSwFallback(m_AdvancedBlendDrawTexture, m_LayerTexture[getCameraIndex()], advancedMode); theRenderContext.SetRenderTarget(*theFB); // setup read target theRenderContext.SetReadTarget(m_AdvancedModeBlendFB); @@ -1428,6 +1435,12 @@ void SLayerRenderData::RunRenderPass(TRenderRenderableFunction inRenderFn, CRegisteredString depthPassStr; + int SLayerRenderData::getCameraIndex() const + { + StereoViews::Enum stereoView = m_Renderer.GetQt3DSContext().GetStereoView(); + return (stereoView == StereoViews::Right) ? 1 : 0; + } + // Render this layer's data to a texture. Required if we have any effects, // prog AA, or if forced. void SLayerRenderData::RenderToTexture() @@ -1467,13 +1480,14 @@ void SLayerRenderData::RunRenderPass(TRenderRenderableFunction inRenderFn, // progressive AA algorithm. if (thePrepResult.m_Flags.WasLayerDataDirty() || thePrepResult.m_Flags.WasDirty() + || (getCameraIndex() == 1 && (m_LeftFlags.WasLayerDataDirty() || m_LeftFlags.WasDirty())) || m_Renderer.IsLayerCachingEnabled() == false) { m_ProgressiveAAPassIndex = 0; m_NonDirtyTemporalAAPassIndex = 0; needsRender = true; } - CResourceTexture2D *renderColorTexture = &m_LayerTexture; + CResourceTexture2D *renderColorTexture = &m_LayerTexture[getCameraIndex()]; CResourceTexture2D *renderPrepassDepthTexture = &m_LayerPrepassDepthTexture; CResourceTexture2D *renderWidgetTexture = &m_LayerWidgetTexture; NVRenderContextScopedProperty<bool> __multisampleEnabled( @@ -1491,7 +1505,7 @@ void SLayerRenderData::RunRenderPass(TRenderRenderableFunction inRenderFn, QT3DSU32 maxTemporalPassIndex = m_Layer.m_TemporalAAEnabled ? 2 : 0; // If all the dimensions match then we do not have to re-render the layer. - if (m_LayerTexture.TextureMatches(theLayerTextureDimensions.width(), + if (m_LayerTexture[getCameraIndex()].TextureMatches(theLayerTextureDimensions.width(), theLayerTextureDimensions.height(), ColorTextureFormat) && (!thePrepResult.m_Flags.RequiresDepthTexture() || m_LayerDepthTexture.TextureMatches(theLayerTextureDimensions.width(), @@ -1567,12 +1581,12 @@ void SLayerRenderData::RunRenderPass(TRenderRenderableFunction inRenderFn, if (isProgressiveAABlendPass || isTemporalAABlendPass) { theBlendShader = m_Renderer.GetLayerProgAABlendShader(); if (theBlendShader) { - m_LayerTexture.EnsureTexture(theLayerOriginalTextureDimensions.width(), + m_LayerTexture[getCameraIndex()].EnsureTexture(theLayerOriginalTextureDimensions.width(), theLayerOriginalTextureDimensions.height(), ColorTextureFormat); QT3DSVec2 theVertexOffsets; if (isProgressiveAABlendPass) { - theLastLayerTexture.StealTexture(m_LayerTexture); + theLastLayerTexture.StealTexture(m_LayerTexture[getCameraIndex()]); aaFactorIndex = (m_ProgressiveAAPassIndex - 1); theVertexOffsets = s_VertexOffsets[aaFactorIndex]; } else { @@ -1580,7 +1594,7 @@ void SLayerRenderData::RunRenderPass(TRenderRenderableFunction inRenderFn, if (temporalAATexture.GetTexture()) theLastLayerTexture.StealTexture(temporalAATexture); else - theLastLayerTexture.StealTexture(m_LayerTexture); + theLastLayerTexture.StealTexture(m_LayerTexture[getCameraIndex()]); } theVertexOffsets = s_TemporalVertexOffsets[m_TemporalAAPassIndex]; @@ -1799,7 +1813,7 @@ void SLayerRenderData::RunRenderPass(TRenderRenderableFunction inRenderFn, if (m_Layer.m_MultisampleAAMode != AAModeValues::SSAA) { // Resolve the FBO to the layer texture CRendererUtil::ResolveMutisampleFBOColorOnly( - theResourceManager, m_LayerTexture, theRenderContext, + theResourceManager, m_LayerTexture[getCameraIndex()], theRenderContext, theLayerTextureDimensions.width(), theLayerTextureDimensions.height(), ColorTextureFormat, *theFB); @@ -1807,7 +1821,7 @@ void SLayerRenderData::RunRenderPass(TRenderRenderableFunction inRenderFn, } else { // Resolve the FBO to the layer texture CRendererUtil::ResolveSSAAFBOColorOnly( - theResourceManager, m_LayerTexture, + theResourceManager, m_LayerTexture[getCameraIndex()], theLayerOriginalTextureDimensions.width(), theLayerOriginalTextureDimensions.height(), theRenderContext, theLayerTextureDimensions.width(), theLayerTextureDimensions.height(), @@ -1855,18 +1869,18 @@ void SLayerRenderData::RunRenderPass(TRenderRenderableFunction inRenderFn, theRenderContext.SetCullingEnabled(false); theRenderContext.SetActiveShader(theBlendShader->m_Shader); theBlendShader->m_AccumSampler.Set(theLastLayerTexture); - theBlendShader->m_LastFrame.Set(m_LayerTexture); + theBlendShader->m_LastFrame.Set(m_LayerTexture[getCameraIndex()]); theBlendShader->m_BlendFactors.Set(theBlendFactors); m_Renderer.RenderQuad(); theFB->Attach(NVRenderFrameBufferAttachments::Color0, qt3ds::render::NVRenderTextureOrRenderBuffer()); if (isTemporalAABlendPass) - temporalAATexture.StealTexture(m_LayerTexture); - m_LayerTexture.StealTexture(targetTexture); + temporalAATexture.StealTexture(m_LayerTexture[getCameraIndex()]); + m_LayerTexture[getCameraIndex()].StealTexture(targetTexture); } - m_LayerTexture->SetMinFilter(NVRenderTextureMinifyingOp::Linear); - m_LayerTexture->SetMagFilter(NVRenderTextureMagnifyingOp::Linear); + m_LayerTexture[getCameraIndex()]->SetMinFilter(NVRenderTextureMinifyingOp::Linear); + m_LayerTexture[getCameraIndex()]->SetMagFilter(NVRenderTextureMagnifyingOp::Linear); // Don't remember why needs widget texture is false here. // Should have commented why progAA plus widgets is a fail. @@ -1906,10 +1920,10 @@ void SLayerRenderData::RunRenderPass(TRenderRenderableFunction inRenderFn, } } if (!effectsActive || !m_Camera) { - if (m_LayerCachedTexture) { + if (m_LayerCachedTexture[getCameraIndex()]) { IResourceManager &theResourceManager(m_Renderer.GetQt3DSContext().GetResourceManager()); - theResourceManager.Release(*m_LayerCachedTexture); - m_LayerCachedTexture = NULL; + theResourceManager.Release(*m_LayerCachedTexture[getCameraIndex()]); + m_LayerCachedTexture[getCameraIndex()] = NULL; } return; } @@ -1917,24 +1931,24 @@ void SLayerRenderData::RunRenderPass(TRenderRenderableFunction inRenderFn, IEffectSystem &theEffectSystem(m_Renderer.GetQt3DSContext().GetEffectSystem()); IResourceManager &theResourceManager(m_Renderer.GetQt3DSContext().GetResourceManager()); // we use the non MSAA buffer for the effect - NVRenderTexture2D *theLayerColorTexture = m_LayerTexture; + NVRenderTexture2D *theLayerColorTexture = m_LayerTexture[getCameraIndex()]; NVRenderTexture2D *theLayerDepthTexture = m_LayerDepthTexture; - if (m_LayerCachedTexture) { + if (m_LayerCachedTexture[getCameraIndex()]) { STextureDetails details(theLayerColorTexture->GetTextureDetails()); - STextureDetails cachedDetails(m_LayerCachedTexture->GetTextureDetails()); + STextureDetails cachedDetails(m_LayerCachedTexture[getCameraIndex()]->GetTextureDetails()); if (cachedDetails.m_Width != details.m_Width || cachedDetails.m_Height != details.m_Height) { - theResourceManager.Release(*m_LayerCachedTexture); - m_LayerCachedTexture = nullptr; + theResourceManager.Release(*m_LayerCachedTexture[getCameraIndex()]); + m_LayerCachedTexture[getCameraIndex()] = nullptr; } } - if (!m_LayerCachedTexture) { + if (!m_LayerCachedTexture[getCameraIndex()]) { STextureDetails details(theLayerColorTexture->GetTextureDetails()); QT3DSU32 finalWidth = ITextRenderer::NextMultipleOf4((QT3DSU32)(details.m_Width)); QT3DSU32 finalHeight = ITextRenderer::NextMultipleOf4((QT3DSU32)(details.m_Height)); - m_LayerCachedTexture = theResourceManager.AllocateTexture2D(finalWidth, finalHeight, + m_LayerCachedTexture[getCameraIndex()] = theResourceManager.AllocateTexture2D(finalWidth, finalHeight, details.m_Format); } @@ -1944,7 +1958,7 @@ void SLayerRenderData::RunRenderPass(TRenderRenderableFunction inRenderFn, if (theEffect->m_Flags.IsActive()) { NVRenderTexture2D *targetTexture = nullptr; if (theEffect == lastEffect) - targetTexture = m_LayerCachedTexture; + targetTexture = m_LayerCachedTexture[getCameraIndex()]; StartProfiling(theEffect->m_ClassName, false); @@ -2039,7 +2053,7 @@ void SLayerRenderData::RunRenderPass(TRenderRenderableFunction inRenderFn, // The render graph should have taken care of the render to texture step. #ifdef QT3DS_CACHED_POST_EFFECT NVRenderTexture2D *theLayerColorTexture = - (m_LayerCachedTexture) ? m_LayerCachedTexture : m_LayerTexture; + (m_LayerCachedTexture[getCameraIndex()]) ? m_LayerCachedTexture[getCameraIndex()] : m_LayerTexture[getCameraIndex()]; #else // Then render all but the last effect IEffectSystem &theEffectSystem(m_Renderer.GetQt3DSContext().GetEffectSystem()); diff --git a/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.h b/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.h index e4c1574..623e8b2 100644 --- a/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.h +++ b/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.h @@ -53,7 +53,7 @@ struct AdvancedBlendModes // Layers can be rendered offscreen for many reasons; effects, progressive aa, // or just because a flag forces it. If they are rendered offscreen we can then // cache the result so we don't render the layer again if it isn't dirty. - CResourceTexture2D m_LayerTexture; + CResourceTexture2D m_LayerTexture[2]; // Multiple temporal AA textures for stereoscopic needs. // First used for mono/left view, second for right view. CResourceTexture2D m_TemporalAATexture[2]; @@ -67,7 +67,7 @@ struct AdvancedBlendModes CResourceTexture2D m_LayerMultisamplePrepassDepthTexture; CResourceTexture2D m_LayerMultisampleWidgetTexture; // the texture contains the render result inclusive post effects - NVRenderTexture2D *m_LayerCachedTexture; + NVRenderTexture2D *m_LayerCachedTexture[2]; NVRenderTexture2D *m_AdvancedBlendDrawTexture; NVRenderTexture2D *m_AdvancedBlendBlendTexture; @@ -99,6 +99,9 @@ struct AdvancedBlendModes QSize m_previousDimensions; QRuntimeViewSignalProxy *m_SignalProxy; + SLayerRenderPreparationResultFlags m_LeftFlags; + + int getCameraIndex() const; SLayerRenderData(SLayer &inLayer, Qt3DSRendererImpl &inRenderer); diff --git a/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.cpp b/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.cpp index 4650e83..f75a673 100644 --- a/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.cpp +++ b/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.cpp @@ -297,13 +297,11 @@ SCameraGlobalCalculationResult SLayerRenderHelper::SetupCameraForRender(SCamera (QT3DSF32)(ITextRenderer::NextMultipleOf4((QT3DSU32)(rect.m_Height / m_ScaleFactor.y))); } // Always calculate main camera variables - if (isStereoscopic()) - m_Camera->CalculateGlobalVariables(rect, m_PresentationDesignDimensions); - // Return current camera variables - auto ret = GetCamera()->CalculateGlobalVariables(rect, m_PresentationDesignDimensions); - - if (isStereoscopic()) + auto ret = m_Camera->CalculateGlobalVariables(rect, m_PresentationDesignDimensions); + if (isStereoscopic()) { + GetCamera()->CalculateGlobalVariables(rect, m_PresentationDesignDimensions); m_Camera->RemoveChild(*GetCamera()); + } return ret; } |