@@ -58,6 +58,9 @@ function rendererWebGPU(p5, fn) {
5858 // Registry to track geometries with buffer pools
5959 this . _geometriesWithPools = [ ] ;
6060
61+ // Reusable Map for uniform buffer bindings to avoid GC
62+ this . _uniformBuffersForBinding = new Map ( ) ;
63+
6164 // Flag to track if any draws have happened that need queue submission
6265 this . _hasPendingDraws = false ;
6366 this . _pendingCommandEncoders = [ ] ;
@@ -584,12 +587,14 @@ function rendererWebGPU(p5, fn) {
584587 // const firstDataView = new DataView(firstData.buffer);
585588
586589 shader . _uniformBufferGroups . push ( {
590+ group : group . group ,
587591 binding : group . binding ,
588592 varName : group . varName ,
589593 structType : group . structType ,
590594 uniforms : groupUniforms ,
591595 size : alignedSize ,
592596 bufferPool : [ ] ,
597+ nextBufferPool : [ ] ,
593598 // bufferPool: [{
594599 // buffer: firstGPUBuffer,
595600 // data: firstData,
@@ -1187,8 +1192,11 @@ function rendererWebGPU(p5, fn) {
11871192 _returnShaderBuffersToPool ( shader ) {
11881193 if ( shader . _uniformBufferGroups ) {
11891194 for ( const bufferGroup of shader . _uniformBufferGroups ) {
1195+ while ( bufferGroup . nextBufferPool . length > 0 ) {
1196+ bufferGroup . bufferPool . push ( bufferGroup . nextBufferPool . pop ( ) ) ;
1197+ }
11901198 for ( const bufferInfo of bufferGroup . buffersInUse . keys ( ) ) {
1191- bufferGroup . bufferPool . push ( bufferInfo ) ;
1199+ bufferGroup . nextBufferPool . push ( bufferInfo ) ;
11921200 }
11931201 // bufferGroup.currentBuffer = null;
11941202 bufferGroup . buffersInUse . clear ( ) ;
@@ -1343,7 +1351,8 @@ function rendererWebGPU(p5, fn) {
13431351 passEncoder . setVertexBuffer ( location , gpuBuffer , 0 ) ;
13441352 }
13451353
1346- const uniformBuffersForBinding = [ ] ;
1354+ // Clear and reuse the map to avoid GC
1355+ this . _uniformBuffersForBinding . clear ( ) ;
13471356
13481357 for ( const bufferGroup of currentShader . _uniformBufferGroups ) {
13491358 let bufferInfo ;
@@ -1368,38 +1377,37 @@ function rendererWebGPU(p5, fn) {
13681377 bufferInfo . data . byteLength
13691378 ) ;
13701379
1371- for ( const uniform of bufferGroup . uniforms ) {
1380+ currentShader . buffersDirty = currentShader . buffersDirty || { } ;
1381+ currentShader . buffersDirty [ bufferGroup . group + ',' + bufferGroup . binding ] = false ;
1382+ /*for (const uniform of bufferGroup.uniforms) {
13721383 const fullUniform = currentShader.uniforms[uniform.name];
13731384 if (fullUniform) {
13741385 fullUniform.dirty = false;
13751386 }
1376- }
1387+ }*/
13771388
13781389 // Cache this buffer and data for next frame
13791390 bufferGroup . currentBuffer = bufferInfo ;
13801391 }
13811392
1382- uniformBuffersForBinding . push ( {
1383- binding : bufferGroup . binding ,
1384- buffer : bufferInfo . buffer
1385- } ) ;
1393+ this . _uniformBuffersForBinding . set ( bufferGroup . binding , bufferInfo . buffer ) ;
13861394 }
13871395
13881396 // Bind sampler/texture uniforms and uniform buffers
13891397 for ( const [ group , entries ] of currentShader . _groupEntries ) {
13901398 const bgEntries = entries . map ( entry => {
13911399 // Check if this is a uniform buffer binding
1392- const uniformBuffer = uniformBuffersForBinding . find ( ub => ub . binding === entry . binding ) ;
1400+ const uniformBuffer = this . _uniformBuffersForBinding . get ( entry . binding ) ;
13931401 if ( uniformBuffer ) {
13941402 return {
13951403 binding : entry . binding ,
1396- resource : { buffer : uniformBuffer . buffer } ,
1404+ resource : { buffer : uniformBuffer } ,
13971405 } ;
13981406 }
13991407
14001408 // This must be a texture/sampler entry
14011409 if ( ! entry . uniform ) {
1402- console . error ( 'Entry missing uniform field:' , entry , 'uniformBuffersForBinding:' , uniformBuffersForBinding ) ;
1410+ console . error ( 'Entry missing uniform field:' , entry , 'uniformBuffersForBinding:' , this . _uniformBuffersForBinding ) ;
14031411 throw new Error (
14041412 `Bind group entry at binding ${ entry . binding } has no uniform field and is not a uniform buffer!`
14051413 ) ;
@@ -1513,6 +1521,7 @@ function rendererWebGPU(p5, fn) {
15131521 _hasGroupDataChanged ( shader , bufferGroup ) {
15141522 // First time
15151523 if ( ! bufferGroup . currentBuffer ) return true ;
1524+ return shader . buffersDirty ?. [ bufferGroup . group + ',' + bufferGroup . binding ] ;
15161525 const cachedData = bufferGroup . currentBuffer . data ;
15171526 const cachedDataView = bufferGroup . currentBuffer . dataView ;
15181527
@@ -1732,15 +1741,16 @@ function rendererWebGPU(p5, fn) {
17321741 // Parse all uniform struct bindings in group 0
17331742 // Each binding represents a logical group of uniforms
17341743 const uniformGroups = [ ] ;
1735- const uniformVarRegex = / @ g r o u p \( 0 \) \s + @ b i n d i n g \( ( \d + ) \) \s + v a r < u n i f o r m > \s + ( \w + ) \s * : \s * ( \w + ) ; / g;
1744+ const uniformVarRegex = / @ g r o u p \( ( \d + ) \) \s + @ b i n d i n g \( ( \d + ) \) \s + v a r < u n i f o r m > \s + ( \w + ) \s * : \s * ( \w + ) ; / g;
17361745
17371746 let match ;
17381747 while ( ( match = uniformVarRegex . exec ( shader . vertSrc ( ) ) ) !== null ) {
1739- const [ _ , binding , varName , structType ] = match ;
1748+ const [ _ , groupNum , binding , varName , structType ] = match ;
17401749 const bindingIndex = parseInt ( binding ) ;
17411750 const uniforms = this . _parseStruct ( shader . vertSrc ( ) , structType ) ;
17421751
17431752 uniformGroups . push ( {
1753+ group : parseInt ( groupNum ) ,
17441754 binding : bindingIndex ,
17451755 varName,
17461756 structType,
@@ -1840,12 +1850,13 @@ function rendererWebGPU(p5, fn) {
18401850 return maxBindingIndex + 1 ;
18411851 }
18421852
1843- updateUniformValue ( _shader , uniform , data ) {
1853+ updateUniformValue ( shader , uniform , data ) {
18441854 if ( uniform . isSampler ) {
18451855 uniform . texture =
18461856 data instanceof Texture ? data : this . getTexture ( data ) ;
18471857 } else {
1848- uniform . dirty = true ;
1858+ shader . buffersDirty = shader . buffersDirty || { } ;
1859+ shader . buffersDirty [ uniform . group + ',' + uniform . binding ] = true ;
18491860 }
18501861 }
18511862
0 commit comments