diff --git a/Source/Engine/Graphics/RenderBuffers.cpp b/Source/Engine/Graphics/RenderBuffers.cpp
index ba00788c4..b1eefd1ec 100644
--- a/Source/Engine/Graphics/RenderBuffers.cpp
+++ b/Source/Engine/Graphics/RenderBuffers.cpp
@@ -295,3 +295,12 @@ void RenderBuffers::Release()
#undef UPDATE_LAZY_KEEP_RT
CustomBuffers.ClearDelete();
}
+
+RenderBuffers::ReadOnlyDepthBuffer RenderBuffers::GetReadOnlyDepthBuffer() const
+{
+ GPUTexture* depthBuffer = DepthBuffer;
+ const bool depthBufferReadOnly = EnumHasAnyFlags(depthBuffer->Flags(), GPUTextureFlags::ReadOnlyDepthView);
+ GPUTextureView* depthBufferRTV = depthBufferReadOnly ? depthBuffer->ViewReadOnlyDepth() : nullptr;
+ GPUTextureView* depthBufferSRV = depthBufferReadOnly ? depthBuffer->ViewReadOnlyDepth() : depthBuffer->View();
+ return { depthBufferRTV, depthBufferSRV };
+}
diff --git a/Source/Engine/Graphics/RenderBuffers.h b/Source/Engine/Graphics/RenderBuffers.h
index fad47c81b..57eb9e372 100644
--- a/Source/Engine/Graphics/RenderBuffers.h
+++ b/Source/Engine/Graphics/RenderBuffers.h
@@ -43,6 +43,15 @@ API_CLASS() class FLAXENGINE_API RenderBuffers : public ScriptingObject
String ToString() const override;
};
+ ///
+ /// Helper container for depth buffer binding as read-only as both shader resource and render target.
+ ///
+ struct ReadOnlyDepthBuffer
+ {
+ GPUTextureView* RTV;
+ GPUTextureView* SRV;
+ };
+
private:
GPUTexture* HalfResDepth = nullptr;
GPUTexture* HiZ = nullptr;
@@ -254,4 +263,9 @@ public:
/// Release the buffers data.
///
API_FUNCTION() void Release();
+
+ ///
+ /// Gets the depth buffer binding for rendering as read-only (both shader resource and render target).
+ ///
+ ReadOnlyDepthBuffer GetReadOnlyDepthBuffer() const;
};
diff --git a/Source/Engine/Renderer/LightPass.cpp b/Source/Engine/Renderer/LightPass.cpp
index 51cb10b42..34c8fb409 100644
--- a/Source/Engine/Renderer/LightPass.cpp
+++ b/Source/Engine/Renderer/LightPass.cpp
@@ -209,11 +209,8 @@ void LightPass::RenderLights(RenderContextBatch& renderContextBatch, GPUTextureV
auto& sphereMesh = _sphereModel->LODs.Get()[0].Meshes.Get()[0];
// Bind output
- GPUTexture* depthBuffer = renderContext.Buffers->DepthBuffer;
- const bool depthBufferReadOnly = EnumHasAnyFlags(depthBuffer->Flags(), GPUTextureFlags::ReadOnlyDepthView);
- GPUTextureView* depthBufferRTV = depthBufferReadOnly ? depthBuffer->ViewReadOnlyDepth() : nullptr;
- GPUTextureView* depthBufferSRV = depthBufferReadOnly ? depthBuffer->ViewReadOnlyDepth() : depthBuffer->View();
- context->SetRenderTarget(depthBufferRTV, lightBuffer);
+ auto depthBuffer = renderContext.Buffers->GetReadOnlyDepthBuffer();
+ context->SetRenderTarget(depthBuffer.RTV, lightBuffer);
// Set per frame data
GBufferPass::SetInputs(renderContext.View, perFrame.GBuffer);
@@ -225,7 +222,7 @@ void LightPass::RenderLights(RenderContextBatch& renderContextBatch, GPUTextureV
context->BindSR(0, renderContext.Buffers->GBuffer0);
context->BindSR(1, renderContext.Buffers->GBuffer1);
context->BindSR(2, renderContext.Buffers->GBuffer2);
- context->BindSR(3, depthBufferSRV);
+ context->BindSR(3, depthBuffer.SRV);
context->BindSR(4, renderContext.Buffers->GBuffer3);
// Fullscreen shadow mask buffer
@@ -256,7 +253,7 @@ void LightPass::RenderLights(RenderContextBatch& renderContextBatch, GPUTextureV
{
GET_SHADOW_MASK();
ShadowsPass::Instance()->RenderShadowMask(renderContextBatch, light, shadowMaskView);
- context->SetRenderTarget(depthBufferRTV, lightBuffer);
+ context->SetRenderTarget(depthBuffer.RTV, lightBuffer);
context->BindSR(5, shadowMaskView);
}
else
@@ -304,7 +301,7 @@ void LightPass::RenderLights(RenderContextBatch& renderContextBatch, GPUTextureV
{
GET_SHADOW_MASK();
ShadowsPass::Instance()->RenderShadowMask(renderContextBatch, light, shadowMaskView);
- context->SetRenderTarget(depthBufferRTV, lightBuffer);
+ context->SetRenderTarget(depthBuffer.RTV, lightBuffer);
context->BindSR(5, shadowMaskView);
}
else
@@ -345,7 +342,7 @@ void LightPass::RenderLights(RenderContextBatch& renderContextBatch, GPUTextureV
{
GET_SHADOW_MASK();
ShadowsPass::Instance()->RenderShadowMask(renderContextBatch, light, shadowMaskView);
- context->SetRenderTarget(depthBufferRTV, lightBuffer);
+ context->SetRenderTarget(depthBuffer.RTV, lightBuffer);
context->BindSR(5, shadowMaskView);
}
else
@@ -448,11 +445,8 @@ void LightPass::RenderDebug(RenderContext& renderContext, GPUContext* context, G
for (auto& light : renderContext.List->DirectionalLights)
baseCost += LIGHT_COMPLEXITY_DIR_COST + (light.HasShadow ? LIGHT_COMPLEXITY_SHADOW_COST : 0);
context->Clear(complexity->View(), Color(baseCost));
- GPUTexture* depthBuffer = renderContext.Buffers->DepthBuffer;
- const bool depthBufferReadOnly = EnumHasAnyFlags(depthBuffer->Flags(), GPUTextureFlags::ReadOnlyDepthView);
- GPUTextureView* depthBufferRTV = depthBufferReadOnly ? depthBuffer->ViewReadOnlyDepth() : nullptr;
- GPUTextureView* depthBufferSRV = depthBufferReadOnly ? depthBuffer->ViewReadOnlyDepth() : depthBuffer->View();
- context->SetRenderTarget(depthBufferRTV, complexity->View());
+ auto depthBuffer = renderContext.Buffers->GetReadOnlyDepthBuffer();
+ context->SetRenderTarget(depthBuffer.RTV, complexity->View());
context->SetViewportAndScissors((float)complexity->Width(), (float)complexity->Height());
for (auto& light : renderContext.List->PointLights)
RenderDebugSphere(renderContext, context, light, light.Radius);
@@ -465,7 +459,7 @@ void LightPass::RenderDebug(RenderContext& renderContext, GPUContext* context, G
// Draw complexity visualization based on accumulated complexity
context->SetRenderTarget(output->View());
context->BindSR(0, complexity->View());
- context->BindSR(3, depthBufferSRV);
+ context->BindSR(3, depthBuffer.SRV);
context->SetState(_psComplexity);
context->DrawFullscreenTriangle();
diff --git a/Source/Engine/Renderer/ReflectionsPass.cpp b/Source/Engine/Renderer/ReflectionsPass.cpp
index c58f60053..f999c095d 100644
--- a/Source/Engine/Renderer/ReflectionsPass.cpp
+++ b/Source/Engine/Renderer/ReflectionsPass.cpp
@@ -236,7 +236,9 @@ void ReflectionsPass::Dispose()
SAFE_DELETE_GPU_RESOURCE(_psProbe);
SAFE_DELETE_GPU_RESOURCE(_psProbeInside);
SAFE_DELETE_GPU_RESOURCE(_psCombinePass);
+#if GPU_ENABLE_DEVELOPMENT
SAFE_DELETE_GPU_RESOURCE(_psDrawSSR);
+#endif
_shader = nullptr;
_boxModel = nullptr;
_sphereModel = nullptr;
@@ -295,14 +297,11 @@ void ReflectionsPass::Render(RenderContext& renderContext, GPUTextureView* light
data.SSRTexelSize = Float2(1.0f / (float)RenderTools::GetResolution(width, ssrSettings.ResolvePassResolution), 1.0f / (float)RenderTools::GetResolution(height, ssrSettings.ResolvePassResolution));
// Bind GBuffer inputs
- GPUTexture* depthBuffer = renderContext.Buffers->DepthBuffer;
- const bool depthBufferReadOnly = EnumHasAnyFlags(depthBuffer->Flags(), GPUTextureFlags::ReadOnlyDepthView);
- GPUTextureView* depthBufferRTV = depthBufferReadOnly ? depthBuffer->ViewReadOnlyDepth() : nullptr;
- GPUTextureView* depthBufferSRV = depthBufferReadOnly ? depthBuffer->ViewReadOnlyDepth() : depthBuffer->View();
+ auto depthBuffer = renderContext.Buffers->GetReadOnlyDepthBuffer();
context->BindSR(0, renderContext.Buffers->GBuffer0);
context->BindSR(1, renderContext.Buffers->GBuffer1);
context->BindSR(2, renderContext.Buffers->GBuffer2);
- context->BindSR(3, depthBufferSRV);
+ context->BindSR(3, depthBuffer.SRV);
auto tempDesc = GPUTextureDescription::New2D(renderContext.Buffers->GetWidth(), renderContext.Buffers->GetHeight(), PixelFormat::R11G11B10_Float);
auto reflectionsBuffer = RenderTargetPool::Get(tempDesc);
@@ -316,7 +315,7 @@ void ReflectionsPass::Render(RenderContext& renderContext, GPUTextureView* light
{
PROFILE_GPU_CPU("Env Probes");
context->SetViewportAndScissors((float)tempDesc.Width, (float)tempDesc.Height);
- context->SetRenderTarget(depthBufferRTV, *reflectionsBuffer);
+ context->SetRenderTarget(depthBuffer.RTV, *reflectionsBuffer);
// Sort probes by the radius
Sorting::QuickSort(renderContext.List->EnvironmentProbes.Get(), renderContext.List->EnvironmentProbes.Count(), &SortProbes);
@@ -381,12 +380,13 @@ void ReflectionsPass::Render(RenderContext& renderContext, GPUTextureView* light
context->BindSR(0, renderContext.Buffers->GBuffer0);
context->BindSR(1, renderContext.Buffers->GBuffer1);
context->BindSR(2, renderContext.Buffers->GBuffer2);
- context->BindSR(3, depthBufferSRV);
+ context->BindSR(3, depthBuffer.SRV);
context->SetViewportAndScissors((float)tempDesc.Width, (float)tempDesc.Height);
}
if (renderContext.View.Mode == ViewMode::Reflections)
{
+#if GPU_ENABLE_DEVELOPMENT
// If SSR is in use, then draw it with alpha blending into reflections buffer
if (ssrBuffer)
{
@@ -405,6 +405,7 @@ void ReflectionsPass::Render(RenderContext& renderContext, GPUTextureView* light
context->DrawFullscreenTriangle();
context->ResetRenderTarget();
}
+#endif
// Override light buffer with the reflections buffer
context->SetRenderTarget(lightBuffer);
@@ -416,7 +417,7 @@ void ReflectionsPass::Render(RenderContext& renderContext, GPUTextureView* light
PROFILE_GPU("Combine");
if (_depthBounds)
{
- context->SetRenderTarget(depthBufferRTV, lightBuffer);
+ context->SetRenderTarget(depthBuffer.RTV, lightBuffer);
context->SetDepthBounds(GPU_DEPTH_RANGE_BOUNDS(GPU_DEPTH_RANGE_MIN, RenderTools::DepthBoundMaxBackground));
}
else
diff --git a/Source/Engine/Renderer/ReflectionsPass.h b/Source/Engine/Renderer/ReflectionsPass.h
index 4cb57c98d..d462d5fcb 100644
--- a/Source/Engine/Renderer/ReflectionsPass.h
+++ b/Source/Engine/Renderer/ReflectionsPass.h
@@ -20,8 +20,9 @@ private:
GPUPipelineState* _psProbe = nullptr;
GPUPipelineState* _psProbeInside = nullptr;
GPUPipelineState* _psCombinePass = nullptr;
+#if GPU_ENABLE_DEVELOPMENT
GPUPipelineState* _psDrawSSR = nullptr;
-
+#endif
AssetReference _sphereModel;
AssetReference _boxModel;
AssetReference _preIntegratedGF;
diff --git a/Source/Engine/Renderer/ShadowsPass.cpp b/Source/Engine/Renderer/ShadowsPass.cpp
index 9b341d467..ae44891e9 100644
--- a/Source/Engine/Renderer/ShadowsPass.cpp
+++ b/Source/Engine/Renderer/ShadowsPass.cpp
@@ -1883,9 +1883,8 @@ void ShadowsPass::RenderShadowMask(RenderContextBatch& renderContextBatch, Rende
context->BindSR(5, shadows.ShadowsBufferView);
context->BindSR(6, shadows.ShadowMapAtlas);
const int32 permutationIndex = shadowQuality + (sperLight.ContactShadowsLength > ZeroTolerance ? 4 : 0);
- GPUTexture* depthBuffer = renderContext.Buffers->DepthBuffer;
- const bool depthBufferReadOnly = EnumHasAnyFlags(depthBuffer->Flags(), GPUTextureFlags::ReadOnlyDepthView);
- context->SetRenderTarget(depthBufferReadOnly ? depthBuffer->ViewReadOnlyDepth() : nullptr, shadowMask);
+ auto depthBuffer = renderContext.Buffers->GetReadOnlyDepthBuffer();
+ context->SetRenderTarget(depthBuffer.RTV, shadowMask);
if (_depthBounds)
{
Float2 minMaxDepth;