@@ -59,9 +59,49 @@ void PipelineLayoutVk::Release(RenderDeviceVkImpl* pDeviceVk, Uint64 CommandQueu
5959 }
6060}
6161
62- void PipelineLayoutVk::Create (RenderDeviceVkImpl* pDeviceVk,
63- RefCntAutoPtr<PipelineResourceSignatureVkImpl> ppSignatures[],
64- Uint32 SignatureCount) noexcept (false )
62+ PipelineLayoutVk::PushConstantInfo PipelineLayoutVk::GetPushConstantInfo (
63+ const RefCntAutoPtr<PipelineResourceSignatureVkImpl>* ppSignatures,
64+ Uint32 SignatureCount)
65+ {
66+ PushConstantInfo PCInfo;
67+ for (Uint32 BindInd = 0 ; BindInd < SignatureCount; ++BindInd)
68+ {
69+ // Signatures are arranged by binding index by PipelineStateBase::CopyResourceSignatures
70+ const RefCntAutoPtr<PipelineResourceSignatureVkImpl>& pSignature = ppSignatures[BindInd];
71+ if (pSignature == nullptr )
72+ continue ;
73+
74+ // Vulkan allows only one push constant range per pipeline layout.
75+ // Diligent API allows multiple inline constant resources, so we promote only the first inline constant
76+ // from resource signatures to push constants. Other inline constants remain uniform buffers.
77+ if (pSignature->HasInlineConstants ())
78+ {
79+ for (Uint32 r = 0 ; r < pSignature->GetTotalResourceCount (); ++r)
80+ {
81+ const PipelineResourceDesc& ResDesc = pSignature->GetResourceDesc (r);
82+ if (ResDesc.Flags & PIPELINE_RESOURCE_FLAG_INLINE_CONSTANTS)
83+ {
84+ VERIFY_EXPR (ResDesc.ArraySize > 0 );
85+ // For inline constants, ArraySize contains the number of 32-bit constants.
86+ PCInfo.Size = ResDesc.ArraySize * sizeof (Uint32);
87+ PCInfo.StageFlags = ShaderTypesToVkShaderStageFlags (ResDesc.ShaderStages );
88+ PCInfo.SignatureIndex = BindInd;
89+ PCInfo.ResourceIndex = r;
90+ break ;
91+ }
92+ }
93+
94+ VERIFY (PCInfo, " pSignature->HasInlineConstants() returned true, but no inline constant resource was found. This is a bug." );
95+ break ;
96+ }
97+ }
98+
99+ return PCInfo;
100+ }
101+
102+ void PipelineLayoutVk::Create (RenderDeviceVkImpl* pDeviceVk,
103+ RefCntAutoPtr<PipelineResourceSignatureVkImpl>* ppSignatures,
104+ Uint32 SignatureCount) noexcept (false )
65105{
66106 VERIFY (m_DescrSetCount == 0 && !m_VkPipelineLayout, " This pipeline layout is already initialized" );
67107
@@ -94,27 +134,6 @@ void PipelineLayoutVk::Create(RenderDeviceVkImpl* pDe
94134#ifdef DILIGENT_DEBUG
95135 m_DbgMaxBindIndex = std::max (m_DbgMaxBindIndex, Uint32{pSignature->GetDesc ().BindingIndex });
96136#endif
97-
98- // Vulkan allows only one push constant range per pipeline layout.
99- // Diligent API allows multiple inline constant resources, so we promote only the first inline constant
100- // from resource signatures to push constants. Other inline constants remain uniform buffers.
101- if (!m_PushConstantInfo && pSignature->HasInlineConstants ())
102- {
103- for (Uint32 r = 0 ; r < pSignature->GetTotalResourceCount (); ++r)
104- {
105- const PipelineResourceDesc& ResDesc = pSignature->GetResourceDesc (r);
106- if (ResDesc.Flags & PIPELINE_RESOURCE_FLAG_INLINE_CONSTANTS)
107- {
108- VERIFY_EXPR (ResDesc.ArraySize > 0 );
109- // For inline constants, ArraySize contains the number of 32-bit constants.
110- m_PushConstantInfo.Size = ResDesc.ArraySize * sizeof (Uint32);
111- m_PushConstantInfo.StageFlags = ShaderTypesToVkShaderStageFlags (ResDesc.ShaderStages );
112- m_PushConstantInfo.SignatureIndex = BindInd;
113- m_PushConstantInfo.ResourceIndex = r;
114- break ;
115- }
116- }
117- }
118137 }
119138 VERIFY_EXPR (DescSetLayoutCount <= MAX_RESOURCE_SIGNATURES * 2 );
120139
@@ -137,42 +156,37 @@ void PipelineLayoutVk::Create(RenderDeviceVkImpl* pDe
137156 " ) used by the pipeline layout exceeds device limit (" , Limits.maxDescriptorSetStorageBuffersDynamic , " )" );
138157 }
139158
140- // Validate push constant size against device limits
141- if (m_PushConstantInfo.Size > Limits.maxPushConstantsSize )
142- {
143- LOG_ERROR_AND_THROW (" Push constant size (" , m_PushConstantInfo.Size ,
144- " bytes) exceeds device limit (" , Limits.maxPushConstantsSize , " bytes)" );
145- }
146-
147- VERIFY (m_DescrSetCount <= std::numeric_limits<decltype (m_DescrSetCount)>::max (),
148- " Descriptor set count (" , DescSetLayoutCount, " ) exceeds the maximum representable value" );
149-
150- VkPipelineLayoutCreateInfo PipelineLayoutCI{};
151- PipelineLayoutCI.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
152- PipelineLayoutCI.pNext = nullptr ;
153- PipelineLayoutCI.flags = 0 ; // reserved for future use
154- PipelineLayoutCI.setLayoutCount = DescSetLayoutCount;
155- PipelineLayoutCI.pSetLayouts = DescSetLayoutCount ? DescSetLayouts.data () : nullptr ;
159+ m_PushConstantInfo = GetPushConstantInfo (ppSignatures, SignatureCount);
156160
157161 // Set up push constant range if present
158162 VkPushConstantRange PushConstantRange{};
159163 if (m_PushConstantInfo)
160164 {
165+ // Validate push constant size against device limits
166+ if (m_PushConstantInfo.Size > Limits.maxPushConstantsSize )
167+ {
168+ LOG_ERROR_AND_THROW (" Push constant size (" , m_PushConstantInfo.Size ,
169+ " bytes) exceeds device limit (" , Limits.maxPushConstantsSize , " bytes)" );
170+ }
171+
161172 PushConstantRange.stageFlags = m_PushConstantInfo.StageFlags ;
162173 PushConstantRange.offset = 0 ;
163174 PushConstantRange.size = m_PushConstantInfo.Size ;
164-
165- PipelineLayoutCI.pushConstantRangeCount = 1 ;
166- PipelineLayoutCI.pPushConstantRanges = &PushConstantRange;
167- }
168- else
169- {
170- PipelineLayoutCI.pushConstantRangeCount = 0 ;
171- PipelineLayoutCI.pPushConstantRanges = nullptr ;
172175 }
173176
177+ VkPipelineLayoutCreateInfo PipelineLayoutCI{};
178+ PipelineLayoutCI.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
179+ PipelineLayoutCI.pNext = nullptr ;
180+ PipelineLayoutCI.flags = 0 ; // reserved for future use
181+ PipelineLayoutCI.setLayoutCount = DescSetLayoutCount;
182+ PipelineLayoutCI.pSetLayouts = DescSetLayoutCount ? DescSetLayouts.data () : nullptr ;
183+ PipelineLayoutCI.pushConstantRangeCount = m_PushConstantInfo ? 1 : 0 ;
184+ PipelineLayoutCI.pPushConstantRanges = m_PushConstantInfo ? &PushConstantRange : nullptr ;
185+
174186 m_VkPipelineLayout = pDeviceVk->GetLogicalDevice ().CreatePipelineLayout (PipelineLayoutCI);
175187
188+ VERIFY (DescSetLayoutCount <= std::numeric_limits<decltype (m_DescrSetCount)>::max (),
189+ " Descriptor set count (" , DescSetLayoutCount, " ) exceeds the maximum representable value" );
176190 m_DescrSetCount = static_cast <Uint8>(DescSetLayoutCount);
177191}
178192
0 commit comments