Simplify binding depth buffer as read-only

This commit is contained in:
2026-06-30 15:18:43 +02:00
parent 1915aa3c06
commit 7d387a11c7
6 changed files with 45 additions and 27 deletions
+9
View File
@@ -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 };
}
+14
View File
@@ -43,6 +43,15 @@ API_CLASS() class FLAXENGINE_API RenderBuffers : public ScriptingObject
String ToString() const override;
};
/// <summary>
/// Helper container for depth buffer binding as read-only as both shader resource and render target.
/// </summary>
struct ReadOnlyDepthBuffer
{
GPUTextureView* RTV;
GPUTextureView* SRV;
};
private:
GPUTexture* HalfResDepth = nullptr;
GPUTexture* HiZ = nullptr;
@@ -254,4 +263,9 @@ public:
/// Release the buffers data.
/// </summary>
API_FUNCTION() void Release();
/// <summary>
/// Gets the depth buffer binding for rendering as read-only (both shader resource and render target).
/// </summary>
ReadOnlyDepthBuffer GetReadOnlyDepthBuffer() const;
};
+9 -15
View File
@@ -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();
+9 -8
View File
@@ -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
+2 -1
View File
@@ -20,8 +20,9 @@ private:
GPUPipelineState* _psProbe = nullptr;
GPUPipelineState* _psProbeInside = nullptr;
GPUPipelineState* _psCombinePass = nullptr;
#if GPU_ENABLE_DEVELOPMENT
GPUPipelineState* _psDrawSSR = nullptr;
#endif
AssetReference<Model> _sphereModel;
AssetReference<Model> _boxModel;
AssetReference<Texture> _preIntegratedGF;
+2 -3
View File
@@ -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;