@@ -821,41 +821,18 @@ void PipelineStateVkImpl::RemapOrVerifyShaderResources(
821821 }
822822}
823823
824- bool PipelineStateVkImpl::InitPushConstantInfoFromSignatures (PushConstantInfoVk& PushConstant,
825- TShaderStages& ShaderStages) const noexcept (false )
824+ void PipelineStateVkImpl::ValidateShaderPushConstants (const TShaderStages& ShaderStages) const noexcept (false )
826825{
827- // Vulkan allows only one push constant range per pipeline layout.
828- // DiligentCore allows multiple inline constant resources, so we promote only the first inline constant
829- // from resource signatures to push constants. Other inline constants remain uniform buffers.
830- const PipelineResourceDesc* pResDesc = nullptr ;
831- const char * PushConstantName = nullptr ;
832- Uint32 PushConstantSize = 0 ;
833- Uint32 PushConstantSignIdx = INVALID_PUSH_CONSTANT_INDEX;
834- Uint32 PushConstantResIdx = INVALID_PUSH_CONSTANT_INDEX;
826+ const Uint32 PushConstantSignIdx = m_PipelineLayout.GetPushConstantSignatureIndex ();
827+ const Uint32 PushConstantResIdx = m_PipelineLayout.GetPushConstantResourceIndex ();
828+ const Uint32 PushConstantSize = m_PipelineLayout.GetPushConstantSize ();
835829
836- for (Uint32 s = 0 ; s < m_SignatureCount; ++s)
830+ const char * PushConstantName = nullptr ;
831+ if (PushConstantSignIdx != INVALID_PUSH_CONSTANT_INDEX && PushConstantResIdx != INVALID_PUSH_CONSTANT_INDEX)
837832 {
838- const PipelineResourceSignatureVkImpl* pSignature = m_Signatures[s];
839- if (pSignature == nullptr )
840- continue ;
841-
842- for (Uint32 r = 0 ; r < pSignature->GetTotalResourceCount (); ++r)
843- {
844- const PipelineResourceDesc& ResDesc = pSignature->GetResourceDesc (r);
845- if ((ResDesc.Flags & PIPELINE_RESOURCE_FLAG_INLINE_CONSTANTS) == 0 )
846- continue ;
847-
848- // For inline constants, ArraySize contains the number of 32-bit constants.
849- PushConstantSize = ResDesc.ArraySize * sizeof (Uint32);
850- PushConstantSignIdx = s;
851- PushConstantResIdx = r;
852- PushConstantName = ResDesc.Name ;
853- pResDesc = &ResDesc;
854- break ;
855- }
856-
857- if (pResDesc != nullptr )
858- break ;
833+ const PipelineResourceSignatureVkImpl* pSignature = m_Signatures[PushConstantSignIdx];
834+ if (pSignature != nullptr )
835+ PushConstantName = pSignature->GetResourceDesc (PushConstantResIdx).Name ;
859836 }
860837
861838 // Validate shader-declared push constants against the selected inline constant (if any).
@@ -871,7 +848,7 @@ bool PipelineStateVkImpl::InitPushConstantInfoFromSignatures(PushConstantInfoVk&
871848 {
872849 const SPIRVShaderResourceAttribs& PCAttribs = pShaderResources->GetPushConstant (pc);
873850
874- if (pResDesc == nullptr )
851+ if (PushConstantName == nullptr )
875852 {
876853 LOG_ERROR_AND_THROW (" Shader '" , pShader->GetDesc ().Name , " ' defines push constants block '" , PCAttribs.Name ,
877854 " ', but the pipeline resource signatures define no inline constant resource to promote to push constants." );
@@ -893,24 +870,6 @@ bool PipelineStateVkImpl::InitPushConstantInfoFromSignatures(PushConstantInfoVk&
893870 }
894871 }
895872 }
896-
897- if (pResDesc == nullptr )
898- {
899- // No inline constants found - PushConstant remains empty.
900- return false ;
901- }
902-
903- PushConstant.Size = PushConstantSize;
904- PushConstant.SignatureIndex = PushConstantSignIdx;
905- PushConstant.ResourceIndex = PushConstantResIdx;
906-
907- for (SHADER_TYPE ShaderTypes = pResDesc->ShaderStages ; ShaderTypes != SHADER_TYPE_UNKNOWN;)
908- {
909- const SHADER_TYPE ShaderType = ExtractLSB (ShaderTypes);
910- PushConstant.StageFlags |= ShaderTypeToVkShaderStageFlagBit (ShaderType);
911- }
912-
913- return true ;
914873}
915874
916875void PipelineStateVkImpl::InitPipelineLayout (const PipelineStateCreateInfo& CreateInfo, TShaderStages& ShaderStages) noexcept (false )
@@ -927,16 +886,15 @@ void PipelineStateVkImpl::InitPipelineLayout(const PipelineStateCreateInfo& Crea
927886 DvpValidateResourceLimits ();
928887#endif
929888
930- // Vulkan allows only one push constant block per pipeline, but it can be accessed from multiple shader stages.
931- // Promote the first inline constant from signatures to push constants (and validate any shader-declared push constants).
932- PushConstantInfoVk PushConstant;
933- InitPushConstantInfoFromSignatures (PushConstant, ShaderStages);
889+ // Create the pipeline layout - this also extracts push constant info from signatures
890+ m_PipelineLayout.Create (GetDevice (), m_Signatures, m_SignatureCount);
934891
935- m_PipelineLayout.Create (GetDevice (), m_Signatures, m_SignatureCount, PushConstant);
892+ // Validate shader-declared push constants against the selected inline constant (if any)
893+ ValidateShaderPushConstants (ShaderStages);
936894
937895 // If we promoted an inline constant as push constant (not an existing SPIR-V push constant),
938896 // convert the uniform buffer to push constant in SPIRV bytecode.
939- PatchShaderConvertUniformBufferToPushConstant (PushConstant, ShaderStages);
897+ PatchShaderConvertUniformBufferToPushConstant (ShaderStages);
940898
941899 const bool RemapResources = (CreateInfo.Flags & PSO_CREATE_FLAG_DONT_REMAP_SHADER_RESOURCES) == 0 ;
942900 const bool VerifyBindings = !RemapResources && ((InternalFlags & PSO_CREATE_INTERNAL_FLAG_NO_SHADER_REFLECTION) == 0 );
@@ -964,20 +922,22 @@ void PipelineStateVkImpl::InitPipelineLayout(const PipelineStateCreateInfo& Crea
964922 }
965923}
966924
967- void PipelineStateVkImpl::PatchShaderConvertUniformBufferToPushConstant (const PushConstantInfoVk& PushConstantInfo,
968- TShaderStages& ShaderStages) const noexcept (false )
925+ void PipelineStateVkImpl::PatchShaderConvertUniformBufferToPushConstant (TShaderStages& ShaderStages) const noexcept (false )
969926{
927+ const Uint32 PushConstantSignIdx = m_PipelineLayout.GetPushConstantSignatureIndex ();
928+ const Uint32 PushConstantResIdx = m_PipelineLayout.GetPushConstantResourceIndex ();
929+
970930 // If no push constant was selected, no patching needed
971- if (PushConstantInfo. SignatureIndex == INVALID_PUSH_CONSTANT_INDEX ||
972- PushConstantInfo. ResourceIndex == INVALID_PUSH_CONSTANT_INDEX)
931+ if (PushConstantSignIdx == INVALID_PUSH_CONSTANT_INDEX ||
932+ PushConstantResIdx == INVALID_PUSH_CONSTANT_INDEX)
973933 return ;
974934
975935 // Get the name of the selected push constant resource
976- const PipelineResourceSignatureVkImpl* pSignature = m_Signatures[PushConstantInfo. SignatureIndex ];
936+ const PipelineResourceSignatureVkImpl* pSignature = m_Signatures[PushConstantSignIdx ];
977937 if (pSignature == nullptr )
978938 return ;
979939
980- const PipelineResourceDesc& ResDesc = pSignature->GetResourceDesc (PushConstantInfo. ResourceIndex );
940+ const PipelineResourceDesc& ResDesc = pSignature->GetResourceDesc (PushConstantResIdx );
981941 const std::string PushConstantName = ResDesc.Name ;
982942
983943 // For each shader stage, check if the uniform buffer needs to be patched
0 commit comments