From 8d2154af26446963ea349e855218989a3d4b577d Mon Sep 17 00:00:00 2001 From: Tommy Walton <82672795+amzn-tommy@users.noreply.github.com> Date: Wed, 30 Jun 2021 11:13:54 -0700 Subject: [PATCH] Partial fix for LYN-2227 : MeshComponent initialization performance improvement (#1381) Skip a shader item before creating a shader instance if it's not going to be rendered based on the draw tag. This avoids creating and releasing the shader instance over and over again, which results in a disk write each time during release. --- .../Code/Source/RPI.Public/MeshDrawPacket.cpp | 51 +++++++++++++------ 1 file changed, 36 insertions(+), 15 deletions(-) diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/MeshDrawPacket.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/MeshDrawPacket.cpp index b29fb6d38d..8a402b5546 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/MeshDrawPacket.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/MeshDrawPacket.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include namespace AZ @@ -154,6 +155,40 @@ namespace AZ auto appendShader = [&](const ShaderCollection::Item& shaderItem) { AZ_PROFILE_SCOPE(Debug::ProfileCategory::AzRender, "appendShader()"); + + // Skip the shader item without creating the shader instance + // if the mesh is not going to be rendered based on the draw tag + RHI::RHISystemInterface* rhiSystem = RHI::RHISystemInterface::Get(); + RHI::DrawListTagRegistry* drawListTagRegistry = rhiSystem->GetDrawListTagRegistry(); + + // Use the explicit draw list override if exists. + RHI::DrawListTag drawListTag = shaderItem.GetDrawListTagOverride(); + + if (drawListTag.IsNull()) + { + Data::Asset shaderAsset = shaderItem.GetShaderAsset(); + if (!shaderAsset.IsReady()) + { + // The shader asset needs to be loaded before we can check the draw tag. + // If it's not loaded yet, the instance database will do a blocking load + // when we create the instance below, so might as well load it now. + shaderAsset.QueueLoad(); + + if (shaderAsset.IsLoading()) + { + shaderAsset.BlockUntilLoadComplete(); + } + } + + drawListTag = drawListTagRegistry->FindTag(shaderAsset->GetDrawListName()); + } + + if (!parentScene.HasOutputForPipelineState(drawListTag)) + { + // drawListTag not found in this scene, so don't render this item + return false; + } + Data::Instance shader = RPI::Shader::FindOrCreate(shaderItem.GetShaderAsset()); if (!shader) { @@ -244,21 +279,7 @@ namespace AZ drawSrg->Compile(); } - // Use the default draw list tag from the shader variant. - RHI::DrawListTag drawListTag = shader->GetDrawListTag(); - - // Use the explicit draw list override if exist. - RHI::DrawListTag runtimeTag = shaderItem.GetDrawListTagOverride(); - if (!runtimeTag.IsNull()) - { - drawListTag = runtimeTag; - } - - if (!parentScene.ConfigurePipelineState(drawListTag, pipelineStateDescriptor)) - { - // drawListTag not found in this scene, so don't render this item - return false; - } + parentScene.ConfigurePipelineState(drawListTag, pipelineStateDescriptor); const RHI::PipelineState* pipelineState = shader->AcquirePipelineState(pipelineStateDescriptor); if (!pipelineState)