@@ -44,8 +44,8 @@ public class GPUSubdivisionContext : IDisposable
44
44
public RenderTexture dummyRenderTarget ;
45
45
46
46
public ComputeBuffer probeVolumesBuffer ;
47
+ public ComputeBuffer brickCountBuffer ;
47
48
public ComputeBuffer [ ] bricksBuffers ;
48
- public ComputeBuffer [ ] readbackCountBuffers ;
49
49
50
50
public Vector4 [ ] brickPositions ;
51
51
@@ -91,14 +91,14 @@ public GPUSubdivisionContext(int probeVolumeCount, ProbeVolumeProfileInfo profil
91
91
maxSubdivisionLevelInSubCell = Mathf . Min ( maxSubdivisionLevel , k_MaxSubdivisionInSubCell ) ;
92
92
maxBrickCountPerAxisInSubCell = ( int ) Mathf . Pow ( 3 , maxSubdivisionLevelInSubCell ) ;
93
93
bricksBuffers = new ComputeBuffer [ maxSubdivisionLevelInSubCell + 1 ] ;
94
- readbackCountBuffers = new ComputeBuffer [ maxSubdivisionLevelInSubCell + 1 ] ;
95
94
for ( int i = 0 ; i <= maxSubdivisionLevelInSubCell ; i ++ )
96
95
{
97
96
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 ) ;
100
98
}
101
99
100
+ brickCountBuffer = new ComputeBuffer ( maxSubdivisionLevelInSubCell + 1 , sizeof ( uint ) , ComputeBufferType . Structured ) ;
101
+
102
102
brickPositions = new Vector4 [ maxBrickCountPerAxisInSubCell * maxBrickCountPerAxisInSubCell * maxBrickCountPerAxisInSubCell ] ;
103
103
}
104
104
@@ -108,16 +108,16 @@ public void Dispose()
108
108
RenderTexture . ReleaseTemporary ( sceneSDF2 ) ;
109
109
RenderTexture . ReleaseTemporary ( dummyRenderTarget ) ;
110
110
probeVolumesBuffer . Release ( ) ;
111
+ brickCountBuffer . Release ( ) ;
111
112
112
113
for ( int i = 0 ; i <= maxSubdivisionLevelInSubCell ; i ++ )
113
- {
114
114
bricksBuffers [ i ] . Release ( ) ;
115
- readbackCountBuffers [ i ] . Release ( ) ;
116
- }
117
115
}
118
116
}
119
117
120
118
static readonly int _BricksToClear = Shader . PropertyToID ( "_BricksToClear" ) ;
119
+ static readonly int _BricksToClearCount = Shader . PropertyToID ( "_BricksToClearCount" ) ;
120
+ static readonly int _BrickCountBuffer = Shader . PropertyToID ( "_BrickCountBuffer" ) ;
121
121
static readonly int _Output = Shader . PropertyToID ( "_Output" ) ;
122
122
static readonly int _OutputSize = Shader . PropertyToID ( "_OutputSize" ) ;
123
123
static readonly int _VolumeWorldOffset = Shader . PropertyToID ( "_VolumeWorldOffset" ) ;
@@ -356,6 +356,9 @@ static void SubdivideSubCell(Bounds cellAABB, ProbeSubdivisionContext subdivisio
356
356
var probeSubdivisionData = ctx . sceneSDF2 ;
357
357
VoxelizeProbeVolumeData ( cmd , cellAABB , probeVolumes , ctx ) ;
358
358
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
+
359
362
// Find the maximum subdivision level we can have in this cell (avoid extra work if not needed)
360
363
int globalMaxSubdiv = ProbeVolumeBakingSet . GetMaxSubdivision ( ctx . maxSubdivisionLevel ) ;
361
364
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
364
367
// Add the bricks from the probe volume min subdivision level:
365
368
int brickCountPerAxis = ( int ) Mathf . Pow ( 3 , ctx . maxSubdivisionLevelInSubCell - subdivisionLevel ) ;
366
369
var bricksBuffer = ctx . bricksBuffers [ subdivisionLevel ] ;
367
- var brickCountReadbackBuffer = ctx . readbackCountBuffers [ subdivisionLevel ] ;
368
370
369
371
using ( new ProfilingScope ( cmd , new ProfilingSampler ( "Clear Bricks Buffer" ) ) )
370
372
{
371
373
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 ) ;
374
377
}
375
378
376
379
// 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 ) ;
378
381
379
- cmd . CopyCounterValue ( bricksBuffer , brickCountReadbackBuffer , 0 ) ;
380
382
// Capture locally the subdivision level to use it inside the lambda
381
383
int localSubdivLevel = subdivisionLevel ;
382
- cmd . RequestAsyncReadback ( brickCountReadbackBuffer , sizeof ( int ) , 0 , ( data ) => {
384
+ cmd . RequestAsyncReadback ( ctx . brickCountBuffer , sizeof ( int ) , subdivisionLevel * sizeof ( int ) , ( data ) => {
383
385
int readbackBrickCount = data . GetData < int > ( ) [ 0 ] ;
384
386
385
387
if ( readbackBrickCount > 0 )
@@ -394,11 +396,13 @@ static void SubdivideSubCell(Bounds cellAABB, ProbeSubdivisionContext subdivisio
394
396
}
395
397
} ) ;
396
398
}
399
+ // ExternalGPUProfiler.BeginGPUCapture();
397
400
398
401
cmd . WaitAllAsyncReadbackRequests ( ) ;
399
402
Graphics . ExecuteCommandBuffer ( cmd ) ;
400
403
cmd . Clear ( ) ;
401
404
CommandBufferPool . Release ( cmd ) ;
405
+ // ExternalGPUProfiler.EndGPUCapture();
402
406
}
403
407
404
408
static bool RasterizeGeometry ( CommandBuffer cmd , Bounds cellAABB , GPUSubdivisionContext ctx , GIContributors contributors )
@@ -633,7 +637,7 @@ static void VoxelizeProbeVolumeData(CommandBuffer cmd, Bounds cellAABB,
633
637
634
638
static void SubdivideFromDistanceField (
635
639
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 )
637
641
{
638
642
using ( new ProfilingScope ( cmd , new ProfilingSampler ( $ "Subdivide Bricks at level { Mathf . Log ( brickCount , 3 ) } ") ) )
639
643
{
@@ -642,6 +646,7 @@ static void SubdivideFromDistanceField(
642
646
Vector3 volumeBrickPosition = ( volume . center - volume . extents - cellOffset ) / minBrickSize ;
643
647
cmd . SetComputeVectorParam ( subdivideSceneCS , _VolumeOffsetInBricks , volumeBrickPosition ) ;
644
648
cmd . SetComputeBufferParam ( subdivideSceneCS , s_SubdivideKernel , _Bricks , buffer ) ;
649
+ cmd . SetComputeBufferParam ( subdivideSceneCS , s_SubdivideKernel , _BrickCountBuffer , brickCountBuffer ) ;
645
650
cmd . SetComputeVectorParam ( subdivideSceneCS , _MaxBrickSize , Vector3 . one * brickCount ) ;
646
651
cmd . SetComputeFloatParam ( subdivideSceneCS , _SubdivisionLevel , subdivisionLevel ) ;
647
652
cmd . SetComputeFloatParam ( subdivideSceneCS , _MaxSubdivisionLevel , ctx . maxSubdivisionLevelInSubCell ) ;
0 commit comments