赞
踩
处理ShadowMapAtlases
FSceneRenderer::RenderShadowDepthMapAtlases(RHICmdList);
- void FSceneRenderer::RenderShadowDepthMapAtlases(FRHICommandListImmediate& RHICmdList)
- {
- check(RHICmdList.IsOutsideRenderPass());
-
- // Perform setup work on all GPUs in case any cached shadows are being updated this
- // frame. We revert to the AllViewsGPUMask for uncached shadows.
- SCOPED_GPU_MASK(RHICmdList, FRHIGPUMask::All());
-
- FSceneRenderTargets& SceneContext = FSceneRenderTargets::Get(RHICmdList);
-
- bool bCanUseParallelDispatch = RHICmdList.IsImmediate() && // translucent shadows are draw on the render thread, using a recursive cmdlist (which is not immediate)
- GRHICommandList.UseParallelAlgorithms() && CVarParallelShadows.GetValueOnRenderThread();
-
- for (int32 AtlasIndex = 0; AtlasIndex < SortedShadowsForShadowDepthPass.ShadowMapAtlases.Num(); AtlasIndex++)
- {
- const FSortedShadowMapAtlas& ShadowMapAtlas = SortedShadowsForShadowDepthPass.ShadowMapAtlases[AtlasIndex];
- FSceneRenderTargetItem& RenderTarget = ShadowMapAtlas.RenderTargets.DepthTarget->GetRenderTargetItem();
- FIntPoint AtlasSize = ShadowMapAtlas.RenderTargets.DepthTarget->GetDesc().Extent;
-
- GVisualizeTexture.SetCheckPoint(RHICmdList, ShadowMapAtlas.RenderTargets.DepthTarget.GetReference());
-
- SCOPED_DRAW_EVENTF(RHICmdList, EventShadowDepths, TEXT("Atlas%u %ux%u"), AtlasIndex, AtlasSize.X, AtlasSize.Y);
-
- auto BeginShadowRenderPass = [this, &RenderTarget, &SceneContext](FRHICommandList& InRHICmdList, bool bPerformClear)
- {
- check(RenderTarget.TargetableTexture->GetDepthClearValue() == 1.0f);
-
- ERenderTargetLoadAction DepthLoadAction = bPerformClear ? ERenderTargetLoadAction::EClear : ERenderTargetLoadAction::ELoad;
-
- FRHIRenderPassInfo RPInfo(RenderTarget.TargetableTexture, MakeDepthStencilTargetActions(MakeRenderTargetActions(DepthLoadAction, ERenderTargetStoreAction::EStore), ERenderTargetActions::DontLoad_DontStore), nullptr, FExclusiveDepthStencil::DepthWrite_StencilNop);
-
- if (!GSupportsDepthRenderTargetWithoutColorRenderTarget)
- {
- RPInfo.ColorRenderTargets[0].Action = ERenderTargetActions::DontLoad_DontStore;
- RPInfo.ColorRenderTargets[0].RenderTarget = SceneContext.GetOptionalShadowDepthColorSurface(InRHICmdList, RPInfo.DepthStencilRenderTarget.DepthStencilTarget->GetTexture2D()->GetSizeX(), RPInfo.DepthStencilRenderTarget.DepthStencilTarget->GetTexture2D()->GetSizeY());
- InRHICmdList.Transition(FRHITransitionInfo(RPInfo.ColorRenderTargets[0].RenderTarget, ERHIAccess::Unknown, ERHIAccess::RTV));
- }
- InRHICmdList.Transition(FRHITransitionInfo(RPInfo.DepthStencilRenderTarget.DepthStencilTarget, ERHIAccess::Unknown, ERHIAccess::DSVWrite));
- InRHICmdList.BeginRenderPass(RPInfo, TEXT("ShadowMapAtlases"));
- };
-
- TArray<FProjectedShadowInfo*, SceneRenderingAllocator> ParallelShadowPasses;
- TArray<FProjectedShadowInfo*, SceneRenderingAllocator> SerialShadowPasses;
-
- // Gather our passes here to minimize switching renderpasses
- for (int32 ShadowIndex = 0; ShadowIndex < ShadowMapAtlas.Shadows.Num(); ShadowIndex++)
- {
- FProjectedShadowInfo* ProjectedShadowInfo = ShadowMapAtlas.Shadows[ShadowIndex];
-
- const bool bDoParallelDispatch = bCanUseParallelDispatch &&
- (ProjectedShadowInfo->IsWholeSceneDirectionalShadow() || CVarParallelShadowsNonWholeScene.GetValueOnRenderThread());
-
- if (bDoParallelDispatch)
- {
- ParallelShadowPasses.Add(ProjectedShadowInfo);
- }
- else
- {
- SerialShadowPasses.Add(ProjectedShadowInfo);
- }
- }
-
- FLightSceneProxy* CurrentLightForDrawEvent = NULL;
-
- #if WANTS_DRAW_MESH_EVENTS
- FDrawEvent LightEvent;
- #endif
-
- if (ParallelShadowPasses.Num() > 0)
- {
- {
- // Clear before going wide.
- SCOPED_DRAW_EVENT(RHICmdList, SetShadowRTsAndClear);
- BeginShadowRenderPass(RHICmdList, true);
- RHICmdList.EndRenderPass();
- }
-
- for (int32 ShadowIndex = 0; ShadowIndex < ParallelShadowPasses.Num(); ShadowIndex++)
- {
- FProjectedShadowInfo* ProjectedShadowInfo = ParallelShadowPasses[ShadowIndex];
- SCOPED_GPU_MASK(RHICmdList, GetGPUMaskForShadow(ProjectedShadowInfo));
-
- if (!CurrentLightForDrawEvent || ProjectedShadowInfo->GetLightSceneInfo().Proxy != CurrentLightForDrawEvent)
- {
- if (CurrentLightForDrawEvent)
- {
- SCOPED_GPU_MASK(RHICmdList, FRHIGPUMask::All());
- STOP_DRAW_EVENT(LightEvent);
- }
-
- CurrentLightForDrawEvent = ProjectedShadowInfo->GetLightSceneInfo().Proxy;
- FString LightNameWithLevel;
- GetLightNameForDrawEvent(CurrentLightForDrawEvent, LightNameWithLevel);
-
- SCOPED_GPU_MASK(RHICmdList, FRHIGPUMask::All());
- BEGIN_DRAW_EVENTF(
- RHICmdList,
- LightNameEvent,
- LightEvent,
- *LightNameWithLevel);
- }
- ProjectedShadowInfo->SetupShadowUniformBuffers(RHICmdList, Scene);
- ProjectedShadowInfo->TransitionCachedShadowmap(RHICmdList, Scene);
- ProjectedShadowInfo->RenderDepth(RHICmdList, this, BeginShadowRenderPass, true);
- }
- }
-
- if (CurrentLightForDrawEvent)
- {
- SCOPED_GPU_MASK(RHICmdList, FRHIGPUMask::All());
- STOP_DRAW_EVENT(LightEvent);
- }
-
- CurrentLightForDrawEvent = nullptr;
-
- if (SerialShadowPasses.Num() > 0)
- {
- bool bShadowDepthCleared = ParallelShadowPasses.Num() > 0;
- bool bForceSingleRenderPass = CVarShadowForceSerialSingleRenderPass.GetValueOnAnyThread() != 0;
- if (bForceSingleRenderPass)
- {
- SCOPED_GPU_MASK(RHICmdList, AllViewsGPUMask);
- BeginShadowRenderPass(RHICmdList, !bShadowDepthCleared);
- }
-
-
- for (int32 ShadowIndex = 0; ShadowIndex < SerialShadowPasses.Num(); ShadowIndex++)
- {
- FProjectedShadowInfo* ProjectedShadowInfo = SerialShadowPasses[ShadowIndex];
- SCOPED_GPU_MASK(RHICmdList, GetGPUMaskForShadow(ProjectedShadowInfo));
-
- if (!CurrentLightForDrawEvent || ProjectedShadowInfo->GetLightSceneInfo().Proxy != CurrentLightForDrawEvent)
- {
- if (CurrentLightForDrawEvent)
- {
- SCOPED_GPU_MASK(RHICmdList, FRHIGPUMask::All());
- STOP_DRAW_EVENT(LightEvent);
- }
-
- CurrentLightForDrawEvent = ProjectedShadowInfo->GetLightSceneInfo().Proxy;
- FString LightNameWithLevel;
- GetLightNameForDrawEvent(CurrentLightForDrawEvent, LightNameWithLevel);
-
- SCOPED_GPU_MASK(RHICmdList, FRHIGPUMask::All());
- BEGIN_DRAW_EVENTF(
- RHICmdList,
- LightNameEvent,
- LightEvent,
- *LightNameWithLevel);
- }
-
- ProjectedShadowInfo->SetupShadowUniformBuffers(RHICmdList, Scene);
- ProjectedShadowInfo->TransitionCachedShadowmap(RHICmdList, Scene);
- #if WITH_MGPU
- // In case the first shadow is view-dependent, ensure we do the clear on all GPUs.
- FRHIGPUMask GPUMaskForRenderPass = RHICmdList.GetGPUMask();
- if (ShadowIndex == 0)
- {
- // This ensures that we don't downgrade the GPU mask if the first shadow is a
- // cached whole scene shadow.
- GPUMaskForRenderPass |= AllViewsGPUMask;
- }
- #endif
- if (!bForceSingleRenderPass)
- {
- SCOPED_GPU_MASK(RHICmdList, GPUMaskForRenderPass);
- BeginShadowRenderPass(RHICmdList, ShadowIndex == 0 && !bShadowDepthCleared);
- }
- ProjectedShadowInfo->RenderDepth(RHICmdList, this, BeginShadowRenderPass, false);
- if (!bForceSingleRenderPass)
- {
- RHICmdList.EndRenderPass();
- }
- }
- if (bForceSingleRenderPass)
- {
- SCOPED_GPU_MASK(RHICmdList, AllViewsGPUMask);
- RHICmdList.EndRenderPass();
- }
- }
-
- if (CurrentLightForDrawEvent)
- {
- SCOPED_GPU_MASK(RHICmdList, FRHIGPUMask::All());
- STOP_DRAW_EVENT(LightEvent);
- CurrentLightForDrawEvent = NULL;
- }
-
- RHICmdList.Transition(FRHITransitionInfo(RenderTarget.TargetableTexture, ERHIAccess::Unknown, ERHIAccess::SRVMask));
- }
- }
- void FProjectedShadowInfo::SetupShadowUniformBuffers(FRHICommandListImmediate& RHICmdList, FScene* Scene, FLightPropagationVolume* LPV)
- {
- const ERHIFeatureLevel::Type FeatureLevel = ShadowDepthView->FeatureLevel;
- if (FSceneInterface::GetShadingPath(FeatureLevel) == EShadingPath::Deferred)
- {
- FShadowDepthPassUniformParameters ShadowDepthPassParameters;
- SetupShadowDepthPassUniformBuffer(this, RHICmdList, *ShadowDepthView, ShadowDepthPassParameters, LPV);
-
- if (IsWholeSceneDirectionalShadow() && !bReflectiveShadowmap)
- {
- check(GetShadowDepthType() == CSMShadowDepthType);
- Scene->UniformBuffers.CSMShadowDepthPassUniformBuffer.UpdateUniformBufferImmediate(ShadowDepthPassParameters);
- }
-
- ShadowDepthPassUniformBuffer.UpdateUniformBufferImmediate(ShadowDepthPassParameters);
-
- if (DependentView)
- {
- extern TSet<IPersistentViewUniformBufferExtension*> PersistentViewUniformBufferExtensions;
-
- for (IPersistentViewUniformBufferExtension* Extension : PersistentViewUniformBufferExtensions)
- {
- Extension->BeginRenderView(DependentView);
- }
- }
- }
-
- // This needs to be done for both mobile and deferred
- UploadDynamicPrimitiveShaderDataForView(RHICmdList, *Scene, *ShadowDepthView);
- }
-
- void FProjectedShadowInfo::TransitionCachedShadowmap(FRHICommandListImmediate& RHICmdList, FScene* Scene)
- {
- if (CacheMode == SDCM_MovablePrimitivesOnly)
- {
- const FCachedShadowMapData& CachedShadowMapData = Scene->CachedShadowMaps.FindChecked(GetLightSceneInfo().Id);
- if (CachedShadowMapData.bCachedShadowMapHasPrimitives && CachedShadowMapData.ShadowMap.IsValid())
- {
- RHICmdList.Transition(FRHITransitionInfo(CachedShadowMapData.ShadowMap.DepthTarget->GetRenderTargetItem().ShaderResourceTexture, ERHIAccess::Unknown, ERHIAccess::SRVGraphics));
- }
- }
- }
- void FProjectedShadowInfo::RenderDepth(FRHICommandListImmediate& RHICmdList, FSceneRenderer* SceneRenderer, FBeginShadowRenderPassFunction BeginShadowRenderPass, bool bDoParallelDispatch)
- {
- #if WANTS_DRAW_MESH_EVENTS
- FString EventName;
-
- if (GetEmitDrawEvents())
- {
- GetShadowTypeNameForDrawEvent(EventName);
- EventName += FString(TEXT(" ")) + FString::FromInt(ResolutionX) + TEXT("x") + FString::FromInt(ResolutionY);
- }
-
- SCOPED_DRAW_EVENTF(RHICmdList, EventShadowDepthActor, *EventName);
- #endif
-
- CONDITIONAL_SCOPE_CYCLE_COUNTER(STAT_RenderWholeSceneShadowDepthsTime, bWholeSceneShadow);
- CONDITIONAL_SCOPE_CYCLE_COUNTER(STAT_RenderPerObjectShadowDepthsTime, !bWholeSceneShadow);
- QUICK_SCOPE_CYCLE_COUNTER(STAT_RenderShadowDepth);
-
- RenderDepthInner(RHICmdList, SceneRenderer, BeginShadowRenderPass, bDoParallelDispatch);
- }
-
- void FProjectedShadowInfo::RenderDepthInner(FRHICommandListImmediate& RHICmdList, FSceneRenderer* SceneRenderer, FBeginShadowRenderPassFunction BeginShadowRenderPass, bool bDoParallelDispatch)
- {
- const ERHIFeatureLevel::Type FeatureLevel = ShadowDepthView->FeatureLevel;
- FRHIUniformBuffer* PassUniformBuffer = ShadowDepthPassUniformBuffer;
-
- const bool bIsWholeSceneDirectionalShadow = IsWholeSceneDirectionalShadow();
-
- if (bIsWholeSceneDirectionalShadow)
- {
- // CSM shadow depth cached mesh draw commands are all referencing the same view uniform buffer. We need to update it before rendering each cascade.
- ShadowDepthView->ViewUniformBuffer.UpdateUniformBufferImmediate(*ShadowDepthView->CachedViewUniformShaderParameters);
-
- if (DependentView)
- {
- extern TSet<IPersistentViewUniformBufferExtension*> PersistentViewUniformBufferExtensions;
-
- for (IPersistentViewUniformBufferExtension* Extension : PersistentViewUniformBufferExtensions)
- {
- Extension->BeginRenderView(DependentView);
- }
- }
- }
-
- if (FSceneInterface::GetShadingPath(FeatureLevel) == EShadingPath::Mobile)
- {
- FMobileShadowDepthPassUniformParameters ShadowDepthPassParameters;
- SetupShadowDepthPassUniformBuffer(this, RHICmdList, *ShadowDepthView, ShadowDepthPassParameters);
- SceneRenderer->Scene->UniformBuffers.MobileCSMShadowDepthPassUniformBuffer.UpdateUniformBufferImmediate(ShadowDepthPassParameters);
- MobileShadowDepthPassUniformBuffer.UpdateUniformBufferImmediate(ShadowDepthPassParameters);
- PassUniformBuffer = SceneRenderer->Scene->UniformBuffers.MobileCSMShadowDepthPassUniformBuffer;
- }
-
- FMeshPassProcessorRenderState DrawRenderState(*ShadowDepthView, PassUniformBuffer);
- SetStateForShadowDepth(bReflectiveShadowmap, bOnePassPointLightShadow, DrawRenderState);
- SetStateForView(RHICmdList);
-
- if (CacheMode == SDCM_MovablePrimitivesOnly)
- {
- // In parallel mode we will not have a renderpass active at this point.
- if (bDoParallelDispatch)
- {
- BeginShadowRenderPass(RHICmdList, false);
- }
-
- // Copy in depths of static primitives before we render movable primitives
- CopyCachedShadowMap(RHICmdList, DrawRenderState, SceneRenderer, *ShadowDepthView);
-
- if (bDoParallelDispatch)
- {
- RHICmdList.EndRenderPass();
- }
- }
-
- if (bDoParallelDispatch)
- {
- check(IsInRenderingThread());
- // Parallel encoding requires its own renderpass.
- check(RHICmdList.IsOutsideRenderPass());
-
- // parallel version
- bool bFlush = CVarRHICmdFlushRenderThreadTasksShadowPass.GetValueOnRenderThread() > 0
- || CVarRHICmdFlushRenderThreadTasks.GetValueOnRenderThread() > 0;
- FScopedCommandListWaitForTasks Flusher(bFlush);
-
- // Dispatch commands
- {
- FShadowParallelCommandListSet ParallelCommandListSet(RHICmdList, *ShadowDepthView, !bFlush, *this, BeginShadowRenderPass);
-
- ShadowDepthPass.DispatchDraw(&ParallelCommandListSet, RHICmdList);
- }
-
- // Renderpass must be closed once we get here.
- check(RHICmdList.IsOutsideRenderPass());
- }
- else
- {
- // We must have already opened the renderpass by the time we get here.
- check(RHICmdList.IsInsideRenderPass());
-
- ShadowDepthPass.DispatchDraw(nullptr, RHICmdList);
-
- // Renderpass must still be open when we reach here
- check(RHICmdList.IsInsideRenderPass());
- }
- }
-
- void FParallelMeshDrawCommandPass::DispatchDraw(FParallelCommandListSet* ParallelCommandListSet, FRHICommandList& RHICmdList) const
- {
- TRACE_CPUPROFILER_EVENT_SCOPE(ParallelMdcDispatchDraw);
- if (MaxNumDraws <= 0)
- {
- return;
- }
-
- FRHIVertexBuffer* PrimitiveIdsBuffer = PrimitiveIdVertexBufferPoolEntry.BufferRHI;
- const int32 BasePrimitiveIdsOffset = 0;
-
- if (ParallelCommandListSet)
- {
- if (TaskContext.bUseGPUScene)
- {
- // Queue a command on the RHI thread which will upload PrimitiveIdVertexBuffer after finishing FMeshDrawCommandPassSetupTask.
- FRHICommandListImmediate &RHICommandList = GetImmediateCommandList_ForRenderCommand();
-
- if (TaskEventRef.IsValid())
- {
- RHICommandList.AddDispatchPrerequisite(TaskEventRef);
- }
-
- RHICommandList.EnqueueLambda([
- VertexBuffer = PrimitiveIdsBuffer,
- VertexBufferData = TaskContext.PrimitiveIdBufferData,
- VertexBufferDataSize = TaskContext.PrimitiveIdBufferDataSize,
- PrimitiveIdVertexBufferPoolEntry = PrimitiveIdVertexBufferPoolEntry](FRHICommandListImmediate& CmdList)
- {
- // Upload vertex buffer data.
- void* RESTRICT Data = (void* RESTRICT)CmdList.LockVertexBuffer(VertexBuffer, 0, VertexBufferDataSize, RLM_WriteOnly);
- FMemory::Memcpy(Data, VertexBufferData, VertexBufferDataSize);
- CmdList.UnlockVertexBuffer(VertexBuffer);
-
- FMemory::Free(VertexBufferData);
- });
-
- RHICommandList.RHIThreadFence(true);
-
- bPrimitiveIdBufferDataOwnedByRHIThread = true;
- }
-
- const ENamedThreads::Type RenderThread = ENamedThreads::GetRenderThread();
-
- FGraphEventArray Prereqs;
- if (ParallelCommandListSet->GetPrereqs())
- {
- Prereqs.Append(*ParallelCommandListSet->GetPrereqs());
- }
- if (TaskEventRef.IsValid())
- {
- Prereqs.Add(TaskEventRef);
- }
-
- // Distribute work evenly to the available task graph workers based on NumEstimatedDraws.
- // Every task will then adjust it's working range based on FVisibleMeshDrawCommandProcessTask results.
- const int32 NumThreads = FMath::Min<int32>(FTaskGraphInterface::Get().GetNumWorkerThreads(), ParallelCommandListSet->Width);
- const int32 NumTasks = FMath::Min<int32>(NumThreads, FMath::DivideAndRoundUp(MaxNumDraws, ParallelCommandListSet->MinDrawsPerCommandList));
- const int32 NumDrawsPerTask = FMath::DivideAndRoundUp(MaxNumDraws, NumTasks);
-
- for (int32 TaskIndex = 0; TaskIndex < NumTasks; TaskIndex++)
- {
- const int32 StartIndex = TaskIndex * NumDrawsPerTask;
- const int32 NumDraws = FMath::Min(NumDrawsPerTask, MaxNumDraws - StartIndex);
- checkSlow(NumDraws > 0);
-
- FRHICommandList* CmdList = ParallelCommandListSet->NewParallelCommandList();
-
- FGraphEventRef AnyThreadCompletionEvent = TGraphTask<FDrawVisibleMeshCommandsAnyThreadTask>::CreateTask(&Prereqs, RenderThread)
- .ConstructAndDispatchWhenReady(*CmdList, TaskContext.MeshDrawCommands, TaskContext.MinimalPipelineStatePassSet, PrimitiveIdsBuffer, BasePrimitiveIdsOffset, TaskContext.bDynamicInstancing, TaskContext.InstanceFactor, TaskIndex, NumTasks);
- ParallelCommandListSet->AddParallelCommandList(CmdList, AnyThreadCompletionEvent, NumDraws);
- }
- }
- else
- {
- QUICK_SCOPE_CYCLE_COUNTER(STAT_MeshPassDrawImmediate);
-
- WaitForMeshPassSetupTask();
-
- if (TaskContext.bUseGPUScene)
- {
- // Can immediately upload vertex buffer data, as there is no parallel draw task.
- void* RESTRICT Data = RHILockVertexBuffer(PrimitiveIdVertexBufferPoolEntry.BufferRHI, 0, TaskContext.PrimitiveIdBufferDataSize, RLM_WriteOnly);
- FMemory::Memcpy(Data, TaskContext.PrimitiveIdBufferData, TaskContext.PrimitiveIdBufferDataSize);
- RHIUnlockVertexBuffer(PrimitiveIdVertexBufferPoolEntry.BufferRHI);
- }
-
- SubmitMeshDrawCommandsRange(TaskContext.MeshDrawCommands, TaskContext.MinimalPipelineStatePassSet, PrimitiveIdsBuffer, BasePrimitiveIdsOffset, TaskContext.bDynamicInstancing, 0, TaskContext.MeshDrawCommands.Num(), TaskContext.InstanceFactor, RHICmdList);
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。