summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAntti Määttä <antti.maatta@qt.io>2023-08-14 13:21:07 +0300
committerAntti Määttä <antti.maatta@qt.io>2023-09-01 15:02:30 +0300
commit2b4ec2230eb21c277d82b80a729f1c8a5e2aee99 (patch)
treed60072dd9dac9cdcaecc3076a052332b8301db44
parentdfba2273014019a8153889d5b91ed7de7758d9f2 (diff)
Fix stereoscopic render layer cachingHEADmaster
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>
-rw-r--r--src/runtimerender/rendererimpl/Qt3DSRendererImpl.cpp16
-rw-r--r--src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.cpp84
-rw-r--r--src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.h7
-rw-r--r--src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.cpp10
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;
}