@@ -56,33 +56,27 @@ namespace
5656{
5757
5858void InitPipelineShaderStages (const VulkanUtilities::LogicalDevice& LogicalDevice,
59- PipelineStateVkImpl::TShaderStages& ShaderStages,
59+ const PipelineStateVkImpl::TShaderStages& ShaderStages,
6060 std::vector<VulkanUtilities::ShaderModuleWrapper>& ShaderModules,
6161 std::vector<VkPipelineShaderStageCreateInfo>& Stages)
6262{
63- for (size_t s = 0 ; s < ShaderStages. size (); ++s )
63+ for (const PipelineStateVkImpl::ShaderStageInfo& Stage : ShaderStages)
6464 {
65- const std::vector<const ShaderVkImpl*>& Shaders = ShaderStages[s].Shaders ;
66- std::vector<std::vector<uint32_t >>& SPIRVs = ShaderStages[s].SPIRVs ;
67- const SHADER_TYPE ShaderType = ShaderStages[s].Type ;
68-
69- VERIFY_EXPR (Shaders.size () == SPIRVs.size ());
70-
7165 VkPipelineShaderStageCreateInfo StageCI{};
7266 StageCI.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
7367 StageCI.pNext = nullptr ;
7468 StageCI.flags = 0 ; // reserved for future use
75- StageCI.stage = ShaderTypeToVkShaderStageFlagBit (ShaderType );
69+ StageCI.stage = ShaderTypeToVkShaderStageFlagBit (Stage. Type );
7670
7771 VkShaderModuleCreateInfo ShaderModuleCI{};
7872 ShaderModuleCI.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
7973 ShaderModuleCI.pNext = nullptr ;
8074 ShaderModuleCI.flags = 0 ;
8175
82- for (size_t i = 0 ; i < Shaders. size (); ++i )
76+ for (const PipelineStateVkImpl::ShaderStageInfo::Item& StageItem : Stage. Items )
8377 {
84- const ShaderVkImpl* pShader = Shaders[i] ;
85- const std::vector<uint32_t > SPIRV = SPIRVs[i] ;
78+ const ShaderVkImpl* pShader = StageItem. pShader ;
79+ const std::vector<uint32_t >& SPIRV = StageItem. SPIRV ;
8680
8781 ShaderModuleCI.codeSize = SPIRV.size () * sizeof (uint32_t );
8882 ShaderModuleCI.pCode = SPIRV.data ();
@@ -415,9 +409,9 @@ std::vector<VkRayTracingShaderGroupCreateInfoKHR> BuildRTShaderGroupDescription(
415409 {
416410 if (ShaderType == Stage.Type )
417411 {
418- for (Uint32 i = 0 ; i < Stage.Shaders .size (); ++i, ++idx)
412+ for (Uint32 i = 0 ; i < Stage.Items .size (); ++i, ++idx)
419413 {
420- if (Stage.Shaders [i] == pShaderVk)
414+ if (Stage.Items [i]. pShader == pShaderVk)
421415 return idx;
422416 }
423417 UNEXPECTED (" Unable to find shader '" , pShaderVk->GetDesc ().Name , " ' in the shader stage. This should never happen and is a bug." );
@@ -554,22 +548,27 @@ void VerifyResourceMerge(const char* PSOName,
554548} // namespace
555549
556550
551+ PipelineStateVkImpl::ShaderStageInfo::Item::Item (const ShaderVkImpl* _pShader) :
552+ pShader{_pShader},
553+ SPIRV{_pShader->GetSPIRV ()}
554+ {
555+ }
556+
557557PipelineStateVkImpl::ShaderStageInfo::ShaderStageInfo (const ShaderVkImpl* pShader) :
558558 Type{pShader->GetDesc ().ShaderType },
559- Shaders{pShader},
560- SPIRVs{pShader->GetSPIRV ()}
559+ Items{Item{pShader}}
561560{}
562561
563562void PipelineStateVkImpl::ShaderStageInfo::Append (const ShaderVkImpl* pShader)
564563{
565564 VERIFY_EXPR (pShader != nullptr );
566- VERIFY (std::find (Shaders .begin (), Shaders .end (), pShader) == Shaders .end (),
565+ VERIFY (std::find_if (Items .begin (), Items .end (), [ pShader]( const Item& I) { return I. pShader == pShader; }) == Items .end (),
567566 " Shader '" , pShader->GetDesc ().Name , " ' already exists in the stage. Shaders must be deduplicated." );
568567
569568 const SHADER_TYPE NewShaderType = pShader->GetDesc ().ShaderType ;
570569 if (Type == SHADER_TYPE_UNKNOWN)
571570 {
572- VERIFY_EXPR (Shaders. empty () && SPIRVs .empty ());
571+ VERIFY_EXPR (Items .empty ());
573572 Type = NewShaderType;
574573 }
575574 else
@@ -578,14 +577,12 @@ void PipelineStateVkImpl::ShaderStageInfo::Append(const ShaderVkImpl* pShader)
578577 " ) of shader '" , pShader->GetDesc ().Name , " ' being added to the stage is inconsistent with the stage type (" ,
579578 GetShaderTypeLiteralName (Type), " )." );
580579 }
581- Shaders.push_back (pShader);
582- SPIRVs.push_back (pShader->GetSPIRV ());
580+ Items.emplace_back (pShader);
583581}
584582
585583size_t PipelineStateVkImpl::ShaderStageInfo::Count () const
586584{
587- VERIFY_EXPR (Shaders.size () == SPIRVs.size ());
588- return Shaders.size ();
585+ return Items.size ();
589586}
590587
591588PipelineResourceSignatureDescWrapper PipelineStateVkImpl::GetDefaultResourceSignatureDesc (
@@ -599,9 +596,9 @@ PipelineResourceSignatureDescWrapper PipelineStateVkImpl::GetDefaultResourceSign
599596 std::unordered_map<ShaderResourceHashKey, const SPIRVShaderResourceAttribs&, ShaderResourceHashKey::Hasher> UniqueResources;
600597 for (const ShaderStageInfo& Stage : ShaderStages)
601598 {
602- for (const ShaderVkImpl* pShader : Stage.Shaders )
599+ for (const ShaderStageInfo::Item& StageItem : Stage.Items )
603600 {
604- const SPIRVShaderResources& ShaderResources = *pShader->GetShaderResources ();
601+ const SPIRVShaderResources& ShaderResources = *StageItem. pShader ->GetShaderResources ();
605602 ShaderResources.ProcessResources (
606603 [&](const SPIRVShaderResourceAttribs& Attribs, Uint32) //
607604 {
@@ -627,7 +624,7 @@ PipelineResourceSignatureDescWrapper PipelineStateVkImpl::GetDefaultResourceSign
627624 {
628625 if (Attribs.ArraySize == 0 )
629626 {
630- LOG_ERROR_AND_THROW (" Resource '" , Attribs.Name , " ' in shader '" , pShader-> GetDesc (). Name , " ' is a runtime-sized array. " ,
627+ LOG_ERROR_AND_THROW (" Resource '" , Attribs.Name , " ' in shader '" , ShaderResources. GetShaderName () , " ' is a runtime-sized array. " ,
631628 " You must use explicit resource signature to specify the array size." );
632629 }
633630
@@ -668,21 +665,21 @@ void PipelineStateVkImpl::RemapOrVerifyShaderResources(
668665
669666 // Verify that pipeline layout is compatible with shader resources and
670667 // remap resource bindings.
671- for (size_t s = 0 ; s < ShaderStages. size (); ++s )
668+ for (ShaderStageInfo& Stage : ShaderStages)
672669 {
673- const std::vector<const ShaderVkImpl*>& Shaders = ShaderStages[s].Shaders ;
674- std::vector<std::vector<uint32_t >>& SPIRVs = ShaderStages[s].SPIRVs ;
675- const SHADER_TYPE ShaderType = ShaderStages[s].Type ;
670+ const SHADER_TYPE ShaderType = Stage.Type ;
676671
677- VERIFY_EXPR (Shaders.size () == SPIRVs.size ());
678-
679- for (size_t i = 0 ; i < Shaders.size (); ++i)
672+ for (ShaderStageInfo::Item& StageItem : Stage.Items )
680673 {
681- const ShaderVkImpl* pShader = Shaders[i];
682- std::vector<uint32_t >& SPIRV = SPIRVs[i];
674+ const char * const ShaderName = StageItem.pShader ->GetDesc ().Name ;
675+ const ShaderResourcesSharedPtr& pShaderResources = StageItem.pShader ->GetShaderResources ();
676+ std::vector<uint32_t >& SPIRV = StageItem.SPIRV ;
683677
684- const auto & pShaderResources = pShader->GetShaderResources ();
685- VERIFY_EXPR (pShaderResources);
678+ if (!pShaderResources)
679+ {
680+ UNEXPECTED (" Shader resources are not initialized for shader '" , ShaderName, " '. This is a bug." );
681+ continue ;
682+ }
686683
687684 if (pDvpShaderResources)
688685 pDvpShaderResources->emplace_back (pShaderResources);
@@ -693,7 +690,7 @@ void PipelineStateVkImpl::RemapOrVerifyShaderResources(
693690 const ResourceAttribution ResAttribution = GetResourceAttribution (SPIRVAttribs.Name , ShaderType, pSignatures, SignatureCount);
694691 if (!ResAttribution)
695692 {
696- LOG_ERROR_AND_THROW (" Shader '" , pShader-> GetDesc (). Name , " ' contains resource '" , SPIRVAttribs.Name ,
693+ LOG_ERROR_AND_THROW (" Shader '" , ShaderName , " ' contains resource '" , SPIRVAttribs.Name ,
697694 " ' that is not present in any pipeline resource signature used to create pipeline state '" ,
698695 PipelineName, " '." );
699696 }
@@ -708,7 +705,7 @@ void PipelineStateVkImpl::RemapOrVerifyShaderResources(
708705 {
709706 const PipelineResourceDesc& ResDesc = ResAttribution.pSignature ->GetResourceDesc (ResAttribution.ResourceIndex );
710707 ValidatePipelineResourceCompatibility (ResDesc, ResType, Flags, SPIRVAttribs.ArraySize ,
711- pShader-> GetDesc (). Name , SignDesc.Name );
708+ ShaderName , SignDesc.Name );
712709
713710 const PipelineResourceSignatureVkImpl::ResourceAttribs& ResAttribs{ResAttribution.pSignature ->GetResourceAttribs (ResAttribution.ResourceIndex )};
714711 ResourceBinding = ResAttribs.BindingIndex ;
@@ -718,7 +715,7 @@ void PipelineStateVkImpl::RemapOrVerifyShaderResources(
718715 {
719716 if (ResType != SHADER_RESOURCE_TYPE_SAMPLER)
720717 {
721- LOG_ERROR_AND_THROW (" Shader '" , pShader-> GetDesc (). Name , " ' contains resource with name '" , SPIRVAttribs.Name ,
718+ LOG_ERROR_AND_THROW (" Shader '" , ShaderName , " ' contains resource with name '" , SPIRVAttribs.Name ,
722719 " ' and type '" , GetShaderResourceTypeLiteralName (ResType),
723720 " ' that is not compatible with immutable sampler defined in pipeline resource signature '" ,
724721 SignDesc.Name , " '." );
@@ -740,13 +737,13 @@ void PipelineStateVkImpl::RemapOrVerifyShaderResources(
740737 const Uint32 SpvDescrSet = SPIRV[SPIRVAttribs.DescriptorSetDecorationOffset ];
741738 if (SpvBinding != ResourceBinding)
742739 {
743- LOG_ERROR_AND_THROW (" Shader '" , pShader-> GetDesc (). Name , " ' maps resource '" , SPIRVAttribs.Name ,
740+ LOG_ERROR_AND_THROW (" Shader '" , ShaderName , " ' maps resource '" , SPIRVAttribs.Name ,
744741 " ' to binding " , SpvBinding, " , but the same resource in pipeline resource signature '" ,
745742 SignDesc.Name , " ' is mapped to binding " , ResourceBinding, ' .' );
746743 }
747744 if (SpvDescrSet != DescriptorSet)
748745 {
749- LOG_ERROR_AND_THROW (" Shader '" , pShader-> GetDesc (). Name , " ' maps resource '" , SPIRVAttribs.Name ,
746+ LOG_ERROR_AND_THROW (" Shader '" , ShaderName , " ' maps resource '" , SPIRVAttribs.Name ,
750747 " ' to descriptor set " , SpvDescrSet, " , but the same resource in pipeline resource signature '" ,
751748 SignDesc.Name , " ' is mapped to set " , DescriptorSet, ' .' );
752749 }
@@ -777,7 +774,7 @@ void PipelineStateVkImpl::RemapOrVerifyShaderResources(
777774 if (!StrippedSPIRV.empty ())
778775 SPIRV = std::move (StrippedSPIRV);
779776 else
780- LOG_ERROR (" Failed to strip reflection information from shader '" , pShader-> GetDesc (). Name , " '. This may indicate a problem with the byte code." );
777+ LOG_ERROR (" Failed to strip reflection information from shader '" , ShaderName , " '. This may indicate a problem with the byte code." );
781778#endif
782779 }
783780 }
@@ -899,7 +896,13 @@ void PipelineStateVkImpl::InitializePipeline(const RayTracingPipelineStateCreate
899896// Used by TPipelineStateBase::Construct()
900897inline std::vector<const ShaderVkImpl*> GetStageShaders (const PipelineStateVkImpl::ShaderStageInfo& Stage)
901898{
902- return Stage.Shaders ;
899+ std::vector<const ShaderVkImpl*> StageShaders;
900+ StageShaders.reserve (Stage.Count ());
901+ for (const PipelineStateVkImpl::ShaderStageInfo::Item& StageItem : Stage.Items )
902+ {
903+ StageShaders.push_back (StageItem.pShader );
904+ }
905+ return StageShaders;
903906}
904907
905908PipelineStateVkImpl::PipelineStateVkImpl (IReferenceCounters* pRefCounters, RenderDeviceVkImpl* pDeviceVk, const GraphicsPipelineStateCreateInfo& CreateInfo) :
0 commit comments