5.3.2存在pso重复编译的问题,麻烦确认一下。
* 配置以下开关,不做postload触发的precache,将Mesh相关的pso编译延迟到MeshDrawCommand::SubmitDrawBegin(…)中:
r.SkipDrawOnPSOPrecaching=1
r.PSOPrecache.Components=0
r.PSOPrecache.Resources=0
r.PSOPrecache.ProxyCreationWhenPSOReady=0
* 表现:如下图,MI_FireArrowBurN_06(2670518295)在不同的线程上被编译了两次;(前面是pso对应的材质名、后面是对应FGraphicsPipelineStateInitializer的hash);
[Image Removed]
* 推测的原因:
RDG使用FParallelMeshDrawCommandPass::DispatchDraw(…)并发处理FDrawVisibleMeshCommandsAnyThreadTask任务时,每个任务最终都会进入FMeshDrawCommand::SubmitDrawBegin(…)。这个方法没有做线程同步。虽然它调用的RetrieveAndCachePSOPrecacheResult(…)、PipelineStateCache::CreateGraphicsPipelineStateAsync(…)内部有做局部范围的同步,但考虑以下情形,仍然会造成pso重复编译:
* FDrawVisibleMeshCommandsAnyThreadTask的两个实例TaskA、TaskB中,对应MeshDrawCommand对应的FGraphicsPipelineStateInitializer是相同的;
* TaskA被分派到线程Background#1、TaskB被分派到BackGround#2,两者并发执行;
* TaskA&B同时进入RetrieveAndCachePSOPrecacheResult(..),执行下图的逻辑:
[Image Removed]
* 两个任务获取的状态都是Missed,因此会各自调用SetGraphicsPipelineState(…),从这里一直到FPSOPrecompileTask->CompilePSO()的执行,都没有做任何检测或同步的,意味着同样的pso可能会被编译多次;
[Image Removed]