@@ -415,6 +415,71 @@ DeviceContextVkImpl::ResourceBindInfo& DeviceContextVkImpl::GetBindInfo(PIPELINE
415415 return m_BindInfo[Indices[Uint32{Type}]];
416416}
417417
418+ void DeviceContextVkImpl::UpdateInlineConstantBuffers (ResourceBindInfo& BindInfo)
419+ {
420+ const PipelineLayoutVk& Layout = m_pPipelineState->GetPipelineLayout ();
421+ const auto & PushConstantInfo = Layout.GetPushConstantInfo ();
422+ const Uint32 SignCount = m_pPipelineState->GetResourceSignatureCount ();
423+
424+ for (Uint32 i = 0 ; i < SignCount; ++i)
425+ {
426+ const PipelineResourceSignatureVkImpl* pSign = m_pPipelineState->GetResourceSignature (i);
427+ if (pSign == nullptr || pSign->GetNumInlineConstantBuffers () == 0 )
428+ continue ;
429+
430+ const ShaderResourceCacheVk* pResourceCache = BindInfo.ResourceCaches [i];
431+ if (pResourceCache == nullptr )
432+ {
433+ // Each signature with inline constants must have a bound SRB with a valid resource cache
434+ DEV_CHECK_ERR (false , " Signature '" , pSign->GetDesc ().Name , " ' has inline constants but no SRB is bound. "
435+ " Did you call CommitShaderResources()?" );
436+ continue ;
437+ }
438+
439+ if (!pResourceCache->HasInlineConstants ())
440+ continue ;
441+
442+ // Determine which resource (if any) in this signature should use push constant path
443+ // If this signature contains the selected push constant, pass its resource index
444+ // Otherwise pass ~0u to use emulated buffer path for all
445+ const Uint32 PushConstantResIndex = (i == PushConstantInfo.SignatureIndex ) ? PushConstantInfo.ResourceIndex : ~0u ;
446+
447+ // Update inline constant buffers
448+ pSign->UpdateInlineConstantBuffers (*pResourceCache, *this , PushConstantResIndex);
449+ }
450+ }
451+
452+ void DeviceContextVkImpl::CommitPushConstants (ResourceBindInfo& BindInfo)
453+ {
454+ VERIFY_EXPR (m_pPipelineState != nullptr );
455+ const PipelineLayoutVk& Layout = m_pPipelineState->GetPipelineLayout ();
456+ const auto & PushConstantInfo = Layout.GetPushConstantInfo ();
457+
458+ if (!PushConstantInfo)
459+ return ;
460+
461+ const PipelineResourceSignatureVkImpl* pSign = m_pPipelineState->GetResourceSignature (PushConstantInfo.SignatureIndex );
462+ VERIFY_EXPR (pSign != nullptr );
463+
464+ const ShaderResourceCacheVk* pResourceCache = BindInfo.ResourceCaches [PushConstantInfo.SignatureIndex ];
465+ if (pResourceCache == nullptr )
466+ {
467+ DEV_CHECK_ERR (false , " Signature '" , pSign->GetDesc ().Name , " ' has push constants but no SRB is bound. "
468+ " Did you call CommitShaderResources()?" );
469+ return ;
470+ }
471+
472+ // Get inline constant data directly from the resource cache
473+ const void * pPushConstantData = pSign->GetPushConstantData (*pResourceCache, PushConstantInfo.ResourceIndex );
474+ if (pPushConstantData == nullptr )
475+ {
476+ DEV_CHECK_ERR (false , " Push constant data is null in signature '" , pSign->GetDesc ().Name , " '" );
477+ return ;
478+ }
479+
480+ m_CommandBuffer.PushConstants (Layout.GetVkPipelineLayout (), PushConstantInfo.vkRange , pPushConstantData);
481+ }
482+
418483void DeviceContextVkImpl::CommitDescriptorSets (ResourceBindInfo& BindInfo, Uint32 CommitSRBMask)
419484{
420485 VERIFY (CommitSRBMask != 0 , " This method should not be called when there is nothing to commit" );
@@ -758,13 +823,28 @@ void DeviceContextVkImpl::PrepareForDraw(DRAW_FLAGS Flags)
758823#endif
759824
760825 ResourceBindInfo& BindInfo = GetBindInfo (PIPELINE_TYPE_GRAPHICS );
826+
827+ // Update inline constant buffers (emulated path) before binding descriptor sets
828+ const bool DynamicBuffersIntact = (Flags & DRAW_FLAG_DYNAMIC_RESOURCE_BUFFERS_INTACT ) != 0 ;
829+ const bool InlineConstantsIntact = (Flags & DRAW_FLAG_INLINE_CONSTANTS_INTACT ) != 0 ;
830+ if (!InlineConstantsIntact)
831+ {
832+ UpdateInlineConstantBuffers (BindInfo);
833+ }
834+
761835 // First time we must always bind descriptor sets with dynamic offsets as SRBs are stale.
762836 // If there are no dynamic buffers bound in the resource cache, for all subsequent
763837 // calls we do not need to bind the sets again.
764- if (Uint32 CommitMask = BindInfo.GetCommitMask (Flags & DRAW_FLAG_DYNAMIC_RESOURCE_BUFFERS_INTACT , Flags & DRAW_FLAG_INLINE_CONSTANTS_INTACT ))
838+ if (Uint32 CommitMask = BindInfo.GetCommitMask (DynamicBuffersIntact, InlineConstantsIntact ))
765839 {
766840 CommitDescriptorSets (BindInfo, CommitMask);
767841 }
842+
843+ // Commit push constants directly from SRB cache.
844+ // Push constants are always submitted before draw (similar to D3D11/D3D12) because
845+ // inline constants are designed to change every draw call.
846+ CommitPushConstants (BindInfo);
847+
768848#ifdef DILIGENT_DEVELOPMENT
769849 // Must be called after CommitDescriptorSets as it needs SetInfo.BaseInd
770850 DvpValidateCommittedShaderResources (BindInfo);
@@ -1059,11 +1139,18 @@ void DeviceContextVkImpl::PrepareForDispatchCompute()
10591139 EndRenderScope ();
10601140
10611141 ResourceBindInfo& BindInfo = GetBindInfo (PIPELINE_TYPE_COMPUTE );
1142+
1143+ // Update inline constant buffers before binding descriptor sets
1144+ UpdateInlineConstantBuffers (BindInfo);
1145+
10621146 if (Uint32 CommitMask = BindInfo.GetCommitMask ())
10631147 {
10641148 CommitDescriptorSets (BindInfo, CommitMask);
10651149 }
10661150
1151+ // Commit push constants directly from SRB cache
1152+ CommitPushConstants (BindInfo);
1153+
10671154#ifdef DILIGENT_DEVELOPMENT
10681155 // Must be called after CommitDescriptorSets as it needs SetInfo.BaseInd
10691156 DvpValidateCommittedShaderResources (BindInfo);
@@ -1075,11 +1162,18 @@ void DeviceContextVkImpl::PrepareForRayTracing()
10751162 EnsureVkCmdBuffer ();
10761163
10771164 ResourceBindInfo& BindInfo = GetBindInfo (PIPELINE_TYPE_RAY_TRACING );
1165+
1166+ // Update inline constant buffers before binding descriptor sets
1167+ UpdateInlineConstantBuffers (BindInfo);
1168+
10781169 if (Uint32 CommitMask = BindInfo.GetCommitMask ())
10791170 {
10801171 CommitDescriptorSets (BindInfo, CommitMask);
10811172 }
10821173
1174+ // Commit push constants directly from SRB cache
1175+ CommitPushConstants (BindInfo);
1176+
10831177#ifdef DILIGENT_DEVELOPMENT
10841178 // Must be called after CommitDescriptorSets as it needs SetInfo.BaseInd
10851179 DvpValidateCommittedShaderResources (BindInfo);
0 commit comments