@@ -15,6 +15,11 @@ public enum DispatchType : byte
1515 Mesh ,
1616}
1717
18+ internal interface ISubCommandList
19+ {
20+ void OnSyncBinding ( uint index ) ;
21+ }
22+
1823/// <summary>
1924/// 命令列表,不支持多线程访问
2025/// </summary>
@@ -327,9 +332,11 @@ public bool SetBinding(CommandList self, ShaderBinding Binding)
327332 internal readonly Dictionary < object , int > m_resources = new ( ) ;
328333 internal readonly Dictionary < FResourceRef , ScopedState > m_scoped_res_state = new ( ) ;
329334 internal readonly HashSet < object > m_objects = new ( ) ;
335+ internal readonly HashSet < ShaderBinding > m_bindings = new ( ) ;
330336 internal GpuOutput ? m_current_output ;
331- internal uint m_grow_cbv_srv_uav_binding_capacity ;
332- internal uint m_grow_sampler_binding_capacity ;
337+ internal uint m_sync_binding_count ;
338+ internal uint m_growing_resource_binding_capacity ;
339+ internal uint m_growing_sampler_binding_capacity ;
333340 internal int m_debug_scope_count ;
334341 internal int m_render_debug_scope_count ;
335342 internal int m_compute_debug_scope_count ;
@@ -385,11 +392,13 @@ internal void Reset()
385392 m_string16 . Clear ( ) ;
386393 m_resources . Clear ( ) ;
387394 m_objects . Clear ( ) ;
388- m_grow_cbv_srv_uav_binding_capacity = 0 ;
389- m_grow_sampler_binding_capacity = 0 ;
395+ m_bindings . Clear ( ) ;
396+ m_current_output = null ;
397+ m_sync_binding_count = 0 ;
398+ m_growing_resource_binding_capacity = 0 ;
399+ m_growing_sampler_binding_capacity = 0 ;
390400 m_current_barrier_cmd_index = - 1 ;
391401 m_auto_barrier = true ;
392- m_current_output = null ;
393402 }
394403
395404 #endregion
@@ -444,8 +453,9 @@ internal void BuildSubmitStruct(GpuExecutor Executor, bool NoWait)
444453 Str16 = p_string16 ,
445454 CommandCount = ( uint ) m_commands . Count ,
446455 ResourceCount = ( uint ) m_resource_metas . Count ,
447- GrowCbvSrvUavBindingCapacity = m_grow_cbv_srv_uav_binding_capacity ,
448- GrowSamplerBindingCapacity = m_grow_sampler_binding_capacity ,
456+ SyncBindingCount = m_sync_binding_count ,
457+ GrowingResourceBindingCapacity = m_growing_resource_binding_capacity ,
458+ GrowingSamplerBindingCapacity = m_growing_sampler_binding_capacity ,
449459 } ;
450460 Queue . ActualSubmit ( Executor , & submit , NoWait ) ;
451461 }
@@ -1315,7 +1325,7 @@ public ComputeScope Compute(string? Name = null, ReadOnlySpan<byte> Name8 = defa
13151325 /// <summary>
13161326 /// 必须在 Render 或者 Compute 范围内使用
13171327 /// </summary>
1318- internal void SyncBinding ( ref PipelineContext context )
1328+ internal void SyncBinding < L > ( ref PipelineContext context , in L list ) where L : ISubCommandList
13191329 {
13201330 var binding = context . CurrentBinding ;
13211331 if ( binding == null ) return ;
@@ -1387,18 +1397,45 @@ internal void SyncBinding(ref PipelineContext context)
13871397 if ( ! ( context . PipelineChanged || context . BindingChanged ) ) return ;
13881398 context . PipelineChanged = false ;
13891399 context . BindingChanged = false ;
1390- if ( binding . Changed )
1400+ var first = m_bindings . Add ( binding ) ;
1401+ list . OnSyncBinding ( m_sync_binding_count ++ ) ;
1402+ if ( first )
13911403 {
13921404 var layout = binding . Layout ;
1393- foreach ( var ( c , g ) in binding . m_changed_groups )
1405+ for ( var c = 0u ; c < layout . NativeGroupClasses . Length ; c ++ )
13941406 {
13951407 ref readonly var @class = ref layout . NativeGroupClasses [ ( int ) c ] ;
1396- ref readonly var group = ref @class . InfoSpan [ ( int ) g ] ;
1397- if ( group . View is FShaderLayoutGroupView . Sampler ) m_grow_sampler_binding_capacity += group . Size ;
1398- else m_grow_cbv_srv_uav_binding_capacity += group . Size ;
1408+ for ( var g = 0u ; g < @class . InfoSpan . Length ; g ++ )
1409+ {
1410+ SyncBindingItem ( binding , layout , c , g , first ) ;
1411+ }
13991412 }
14001413 binding . ApplyChange ( ) ;
14011414 }
1415+ else if ( binding . Changed )
1416+ {
1417+ var layout = binding . Layout ;
1418+ foreach ( var ( c , g ) in binding . m_changed_groups )
1419+ {
1420+ SyncBindingItem ( binding , layout , c , g , first ) ;
1421+ }
1422+ binding . ApplyChange ( ) ;
1423+ }
1424+ }
1425+
1426+ private void SyncBindingItem ( ShaderBinding binding , ShaderLayout layout , uint c , uint g , bool first )
1427+ {
1428+ ref readonly var @class = ref layout . NativeGroupClasses [ ( int ) c ] ;
1429+ ref readonly var group = ref @class . InfoSpan [ ( int ) g ] ;
1430+ if ( @class . Scope != FShaderLayoutGroupScope . Persist ) goto Add ;
1431+ if ( ! first ) goto Add ;
1432+ var changed = binding . m_changed_groups . Contains ( ( c , g ) ) ;
1433+ if ( changed ) goto Add ;
1434+ return ;
1435+ Add :
1436+ if ( @class . Sampler ) m_growing_sampler_binding_capacity += group . Size ;
1437+ else m_growing_resource_binding_capacity += group . Size ;
1438+ return ;
14021439 }
14031440
14041441 #endregion
@@ -1571,7 +1608,7 @@ public unsafe struct RenderScope(
15711608 FCommandRender render_cmd ,
15721609 List < FRenderCommandItem > m_commands ,
15731610 bool debug_scope
1574- ) : IDisposable
1611+ ) : IDisposable , ISubCommandList
15751612{
15761613 #region Fields
15771614
@@ -1931,7 +1968,7 @@ public void Draw(
19311968 throw new ArgumentException ( "Only shaders with a vertex stage can use Draw" ) ;
19321969 }
19331970 if ( Binding != null ) SetBinding ( Binding ) ;
1934- self . SyncBinding ( ref m_context ) ;
1971+ self . SyncBinding ( ref m_context , this ) ;
19351972 var cmd = new FCommandDraw
19361973 {
19371974 Base = { Type = FCommandType . Draw } ,
@@ -1975,7 +2012,7 @@ public void DispatchMesh(
19752012 throw new ArgumentException ( "Only shaders with a mesh stage can use DispatchMesh" ) ;
19762013 }
19772014 if ( Binding != null ) SetBinding ( Binding ) ;
1978- self . SyncBinding ( ref m_context ) ;
2015+ self . SyncBinding ( ref m_context , this ) ;
19792016 var cmd = new FCommandDispatch
19802017 {
19812018 Base = { Type = FCommandType . Draw } ,
@@ -1991,6 +2028,20 @@ public void DispatchMesh(
19912028 }
19922029
19932030 #endregion
2031+
2032+ #region OnSyncBinding
2033+
2034+ void ISubCommandList . OnSyncBinding ( uint index )
2035+ {
2036+ var cmd = new FCommandSyncBinding
2037+ {
2038+ Base = { Type = FCommandType . SyncBinding } ,
2039+ Index = index ,
2040+ } ;
2041+ m_commands . Add ( new ( ) { SyncBinding = cmd } ) ;
2042+ }
2043+
2044+ #endregion
19942045}
19952046
19962047#endregion
@@ -2003,7 +2054,7 @@ public unsafe struct ComputeScope(
20032054 FCommandCompute compute_cmd ,
20042055 List < FComputeCommandItem > m_commands ,
20052056 bool debug_scope
2006- ) : IDisposable
2057+ ) : IDisposable , ISubCommandList
20072058{
20082059 #region Fields
20092060
@@ -2238,7 +2289,7 @@ public void Dispatch(
22382289 throw new ArgumentException ( "Only Compute shaders can use Dispatch" ) ;
22392290 m_has_compute_shader = true ;
22402291 }
2241- self . SyncBinding ( ref m_context ) ;
2292+ self . SyncBinding ( ref m_context , this ) ;
22422293 var cmd = new FCommandDispatch
22432294 {
22442295 Base = { Type = FCommandType . SetBinding } ,
@@ -2257,6 +2308,20 @@ public void Dispatch(
22572308 }
22582309
22592310 #endregion
2311+
2312+ #region OnSyncBinding
2313+
2314+ void ISubCommandList . OnSyncBinding ( uint index )
2315+ {
2316+ var cmd = new FCommandSyncBinding
2317+ {
2318+ Base = { Type = FCommandType . SyncBinding } ,
2319+ Index = index ,
2320+ } ;
2321+ m_commands . Add ( new ( ) { SyncBinding = cmd } ) ;
2322+ }
2323+
2324+ #endregion
22602325}
22612326
22622327#endregion
0 commit comments