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;