@@ -15,6 +15,11 @@ public enum DispatchType : byte
15
15
Mesh ,
16
16
}
17
17
18
+ internal interface ISubCommandList
19
+ {
20
+ void OnSyncBinding ( uint index ) ;
21
+ }
22
+
18
23
/// <summary>
19
24
/// 命令列表,不支持多线程访问
20
25
/// </summary>
@@ -327,9 +332,11 @@ public bool SetBinding(CommandList self, ShaderBinding Binding)
327
332
internal readonly Dictionary < object , int > m_resources = new ( ) ;
328
333
internal readonly Dictionary < FResourceRef , ScopedState > m_scoped_res_state = new ( ) ;
329
334
internal readonly HashSet < object > m_objects = new ( ) ;
335
+ internal readonly HashSet < ShaderBinding > m_bindings = new ( ) ;
330
336
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 ;
333
340
internal int m_debug_scope_count ;
334
341
internal int m_render_debug_scope_count ;
335
342
internal int m_compute_debug_scope_count ;
@@ -385,11 +392,13 @@ internal void Reset()
385
392
m_string16 . Clear ( ) ;
386
393
m_resources . Clear ( ) ;
387
394
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 ;
390
400
m_current_barrier_cmd_index = - 1 ;
391
401
m_auto_barrier = true ;
392
- m_current_output = null ;
393
402
}
394
403
395
404
#endregion
@@ -444,8 +453,9 @@ internal void BuildSubmitStruct(GpuExecutor Executor, bool NoWait)
444
453
Str16 = p_string16 ,
445
454
CommandCount = ( uint ) m_commands . Count ,
446
455
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 ,
449
459
} ;
450
460
Queue . ActualSubmit ( Executor , & submit , NoWait ) ;
451
461
}
@@ -1315,7 +1325,7 @@ public ComputeScope Compute(string? Name = null, ReadOnlySpan<byte> Name8 = defa
1315
1325
/// <summary>
1316
1326
/// 必须在 Render 或者 Compute 范围内使用
1317
1327
/// </summary>
1318
- internal void SyncBinding ( ref PipelineContext context )
1328
+ internal void SyncBinding < L > ( ref PipelineContext context , in L list ) where L : ISubCommandList
1319
1329
{
1320
1330
var binding = context . CurrentBinding ;
1321
1331
if ( binding == null ) return ;
@@ -1387,18 +1397,45 @@ internal void SyncBinding(ref PipelineContext context)
1387
1397
if ( ! ( context . PipelineChanged || context . BindingChanged ) ) return ;
1388
1398
context . PipelineChanged = false ;
1389
1399
context . BindingChanged = false ;
1390
- if ( binding . Changed )
1400
+ var first = m_bindings . Add ( binding ) ;
1401
+ list . OnSyncBinding ( m_sync_binding_count ++ ) ;
1402
+ if ( first )
1391
1403
{
1392
1404
var layout = binding . Layout ;
1393
- foreach ( var ( c , g ) in binding . m_changed_groups )
1405
+ for ( var c = 0u ; c < layout . NativeGroupClasses . Length ; c ++ )
1394
1406
{
1395
1407
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
+ }
1399
1412
}
1400
1413
binding . ApplyChange ( ) ;
1401
1414
}
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 ;
1402
1439
}
1403
1440
1404
1441
#endregion
@@ -1571,7 +1608,7 @@ public unsafe struct RenderScope(
1571
1608
FCommandRender render_cmd ,
1572
1609
List < FRenderCommandItem > m_commands ,
1573
1610
bool debug_scope
1574
- ) : IDisposable
1611
+ ) : IDisposable , ISubCommandList
1575
1612
{
1576
1613
#region Fields
1577
1614
@@ -1931,7 +1968,7 @@ public void Draw(
1931
1968
throw new ArgumentException ( "Only shaders with a vertex stage can use Draw" ) ;
1932
1969
}
1933
1970
if ( Binding != null ) SetBinding ( Binding ) ;
1934
- self . SyncBinding ( ref m_context ) ;
1971
+ self . SyncBinding ( ref m_context , this ) ;
1935
1972
var cmd = new FCommandDraw
1936
1973
{
1937
1974
Base = { Type = FCommandType . Draw } ,
@@ -1975,7 +2012,7 @@ public void DispatchMesh(
1975
2012
throw new ArgumentException ( "Only shaders with a mesh stage can use DispatchMesh" ) ;
1976
2013
}
1977
2014
if ( Binding != null ) SetBinding ( Binding ) ;
1978
- self . SyncBinding ( ref m_context ) ;
2015
+ self . SyncBinding ( ref m_context , this ) ;
1979
2016
var cmd = new FCommandDispatch
1980
2017
{
1981
2018
Base = { Type = FCommandType . Draw } ,
@@ -1991,6 +2028,20 @@ public void DispatchMesh(
1991
2028
}
1992
2029
1993
2030
#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
1994
2045
}
1995
2046
1996
2047
#endregion
@@ -2003,7 +2054,7 @@ public unsafe struct ComputeScope(
2003
2054
FCommandCompute compute_cmd ,
2004
2055
List < FComputeCommandItem > m_commands ,
2005
2056
bool debug_scope
2006
- ) : IDisposable
2057
+ ) : IDisposable , ISubCommandList
2007
2058
{
2008
2059
#region Fields
2009
2060
@@ -2238,7 +2289,7 @@ public void Dispatch(
2238
2289
throw new ArgumentException ( "Only Compute shaders can use Dispatch" ) ;
2239
2290
m_has_compute_shader = true ;
2240
2291
}
2241
- self . SyncBinding ( ref m_context ) ;
2292
+ self . SyncBinding ( ref m_context , this ) ;
2242
2293
var cmd = new FCommandDispatch
2243
2294
{
2244
2295
Base = { Type = FCommandType . SetBinding } ,
@@ -2257,6 +2308,20 @@ public void Dispatch(
2257
2308
}
2258
2309
2259
2310
#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
2260
2325
}
2261
2326
2262
2327
#endregion
0 commit comments