@@ -44,8 +44,8 @@ public class GPUSubdivisionContext : IDisposable
4444 public RenderTexture dummyRenderTarget ;
4545
4646 public ComputeBuffer probeVolumesBuffer ;
47+ public ComputeBuffer brickCountBuffer ;
4748 public ComputeBuffer [ ] bricksBuffers ;
48- public ComputeBuffer [ ] readbackCountBuffers ;
4949
5050 public Vector4 [ ] brickPositions ;
5151
@@ -91,14 +91,14 @@ public GPUSubdivisionContext(int probeVolumeCount, ProbeVolumeProfileInfo profil
9191 maxSubdivisionLevelInSubCell = Mathf . Min ( maxSubdivisionLevel , k_MaxSubdivisionInSubCell ) ;
9292 maxBrickCountPerAxisInSubCell = ( int ) Mathf . Pow ( 3 , maxSubdivisionLevelInSubCell ) ;
9393 bricksBuffers = new ComputeBuffer [ maxSubdivisionLevelInSubCell + 1 ] ;
94- readbackCountBuffers = new ComputeBuffer [ maxSubdivisionLevelInSubCell + 1 ] ;
9594 for ( int i = 0 ; i <= maxSubdivisionLevelInSubCell ; i ++ )
9695 {
9796 int brickCountPerAxis = ( int ) Mathf . Pow ( 3 , maxSubdivisionLevelInSubCell - i ) ;
98- bricksBuffers [ i ] = new ComputeBuffer ( brickCountPerAxis * brickCountPerAxis * brickCountPerAxis , sizeof ( float ) * 4 , ComputeBufferType . Append ) ;
99- readbackCountBuffers [ i ] = new ComputeBuffer ( 1 , sizeof ( int ) , ComputeBufferType . Raw ) ;
97+ bricksBuffers [ i ] = new ComputeBuffer ( brickCountPerAxis * brickCountPerAxis * brickCountPerAxis , sizeof ( float ) * 4 , ComputeBufferType . Structured ) ;
10098 }
10199
100+ brickCountBuffer = new ComputeBuffer ( maxSubdivisionLevelInSubCell + 1 , sizeof ( uint ) , ComputeBufferType . Structured ) ;
101+
102102 brickPositions = new Vector4 [ maxBrickCountPerAxisInSubCell * maxBrickCountPerAxisInSubCell * maxBrickCountPerAxisInSubCell ] ;
103103 }
104104
@@ -108,16 +108,16 @@ public void Dispose()
108108 RenderTexture . ReleaseTemporary ( sceneSDF2 ) ;
109109 RenderTexture . ReleaseTemporary ( dummyRenderTarget ) ;
110110 probeVolumesBuffer . Release ( ) ;
111+ brickCountBuffer . Release ( ) ;
111112
112113 for ( int i = 0 ; i <= maxSubdivisionLevelInSubCell ; i ++ )
113- {
114114 bricksBuffers [ i ] . Release ( ) ;
115- readbackCountBuffers [ i ] . Release ( ) ;
116- }
117115 }
118116 }
119117
120118 static readonly int _BricksToClear = Shader . PropertyToID ( "_BricksToClear" ) ;
119+ static readonly int _BricksToClearCount = Shader . PropertyToID ( "_BricksToClearCount" ) ;
120+ static readonly int _BrickCountBuffer = Shader . PropertyToID ( "_BrickCountBuffer" ) ;
121121 static readonly int _Output = Shader . PropertyToID ( "_Output" ) ;
122122 static readonly int _OutputSize = Shader . PropertyToID ( "_OutputSize" ) ;
123123 static readonly int _VolumeWorldOffset = Shader . PropertyToID ( "_VolumeWorldOffset" ) ;
@@ -356,6 +356,9 @@ static void SubdivideSubCell(Bounds cellAABB, ProbeSubdivisionContext subdivisio
356356 var probeSubdivisionData = ctx . sceneSDF2 ;
357357 VoxelizeProbeVolumeData ( cmd , cellAABB , probeVolumes , ctx ) ;
358358
359+ // Clear the brick counter, equivalent to SetBufferCounterValue(0) but we can't use append buffers
360+ cmd . SetBufferData ( ctx . brickCountBuffer , new int [ ctx . maxSubdivisionLevelInSubCell + 1 ] ) ;
361+
359362 // Find the maximum subdivision level we can have in this cell (avoid extra work if not needed)
360363 int globalMaxSubdiv = ProbeVolumeBakingSet . GetMaxSubdivision ( ctx . maxSubdivisionLevel ) ;
361364 int startSubdivisionLevel = Mathf . Max ( 0 , ctx . maxSubdivisionLevelInSubCell - GetMaxSubdivision ( ctx , probeVolumes . Max ( p => p . component . GetMaxSubdivMultiplier ( globalMaxSubdiv ) ) ) ) ;
@@ -364,22 +367,21 @@ static void SubdivideSubCell(Bounds cellAABB, ProbeSubdivisionContext subdivisio
364367 // Add the bricks from the probe volume min subdivision level:
365368 int brickCountPerAxis = ( int ) Mathf . Pow ( 3 , ctx . maxSubdivisionLevelInSubCell - subdivisionLevel ) ;
366369 var bricksBuffer = ctx . bricksBuffers [ subdivisionLevel ] ;
367- var brickCountReadbackBuffer = ctx . readbackCountBuffers [ subdivisionLevel ] ;
368370
369371 using ( new ProfilingScope ( cmd , new ProfilingSampler ( "Clear Bricks Buffer" ) ) )
370372 {
371373 cmd . SetComputeBufferParam ( subdivideSceneCS , s_ClearBufferKernel , _BricksToClear , bricksBuffer ) ;
372- DispatchCompute ( cmd , s_ClearBufferKernel , brickCountPerAxis * brickCountPerAxis * brickCountPerAxis , 1 ) ;
373- cmd . SetBufferCounterValue ( bricksBuffer , 0 ) ;
374+ int count = brickCountPerAxis * brickCountPerAxis * brickCountPerAxis ;
375+ cmd . SetComputeIntParam ( subdivideSceneCS , _BricksToClearCount , count ) ;
376+ DispatchCompute ( cmd , s_ClearBufferKernel , count , 1 ) ;
374377 }
375378
376379 // Generate the list of bricks on the GPU
377- SubdivideFromDistanceField ( cmd , cellAABB , ctx , probeSubdivisionData , bricksBuffer , brickCountPerAxis , subdivisionLevel , minBrickSize , cellOffset ) ;
380+ SubdivideFromDistanceField ( cmd , cellAABB , ctx , probeSubdivisionData , bricksBuffer , ctx . brickCountBuffer , brickCountPerAxis , subdivisionLevel , minBrickSize , cellOffset ) ;
378381
379- cmd . CopyCounterValue ( bricksBuffer , brickCountReadbackBuffer , 0 ) ;
380382 // Capture locally the subdivision level to use it inside the lambda
381383 int localSubdivLevel = subdivisionLevel ;
382- cmd . RequestAsyncReadback ( brickCountReadbackBuffer , sizeof ( int ) , 0 , ( data ) => {
384+ cmd . RequestAsyncReadback ( ctx . brickCountBuffer , sizeof ( int ) , subdivisionLevel * sizeof ( int ) , ( data ) => {
383385 int readbackBrickCount = data . GetData < int > ( ) [ 0 ] ;
384386
385387 if ( readbackBrickCount > 0 )
@@ -394,11 +396,13 @@ static void SubdivideSubCell(Bounds cellAABB, ProbeSubdivisionContext subdivisio
394396 }
395397 } ) ;
396398 }
399+ // ExternalGPUProfiler.BeginGPUCapture();
397400
398401 cmd . WaitAllAsyncReadbackRequests ( ) ;
399402 Graphics . ExecuteCommandBuffer ( cmd ) ;
400403 cmd . Clear ( ) ;
401404 CommandBufferPool . Release ( cmd ) ;
405+ // ExternalGPUProfiler.EndGPUCapture();
402406 }
403407
404408 static bool RasterizeGeometry ( CommandBuffer cmd , Bounds cellAABB , GPUSubdivisionContext ctx , GIContributors contributors )
@@ -633,7 +637,7 @@ static void VoxelizeProbeVolumeData(CommandBuffer cmd, Bounds cellAABB,
633637
634638 static void SubdivideFromDistanceField (
635639 CommandBuffer cmd , Bounds volume , GPUSubdivisionContext ctx , RenderTexture probeVolumeData ,
636- ComputeBuffer buffer , int brickCount , int subdivisionLevel , float minBrickSize , Vector3 cellOffset )
640+ ComputeBuffer buffer , ComputeBuffer brickCountBuffer , int brickCount , int subdivisionLevel , float minBrickSize , Vector3 cellOffset )
637641 {
638642 using ( new ProfilingScope ( cmd , new ProfilingSampler ( $ "Subdivide Bricks at level { Mathf . Log ( brickCount , 3 ) } ") ) )
639643 {
@@ -642,6 +646,7 @@ static void SubdivideFromDistanceField(
642646 Vector3 volumeBrickPosition = ( volume . center - volume . extents - cellOffset ) / minBrickSize ;
643647 cmd . SetComputeVectorParam ( subdivideSceneCS , _VolumeOffsetInBricks , volumeBrickPosition ) ;
644648 cmd . SetComputeBufferParam ( subdivideSceneCS , s_SubdivideKernel , _Bricks , buffer ) ;
649+ cmd . SetComputeBufferParam ( subdivideSceneCS , s_SubdivideKernel , _BrickCountBuffer , brickCountBuffer ) ;
645650 cmd . SetComputeVectorParam ( subdivideSceneCS , _MaxBrickSize , Vector3 . one * brickCount ) ;
646651 cmd . SetComputeFloatParam ( subdivideSceneCS , _SubdivisionLevel , subdivisionLevel ) ;
647652 cmd . SetComputeFloatParam ( subdivideSceneCS , _MaxSubdivisionLevel , ctx . maxSubdivisionLevelInSubCell ) ;
0 commit comments