|
@@ -29,11 +29,16 @@ class Pipelines extends DataMap {
|
|
|
|
|
|
const data = this.get( computeNode );
|
|
|
|
|
|
- if ( data.pipeline === undefined ) {
|
|
|
+ if ( this._needsComputeUpdate( computeNode ) ) {
|
|
|
|
|
|
- // release previous cache
|
|
|
+ const previousPipeline = data.pipeline;
|
|
|
|
|
|
- const previousPipeline = this._releasePipeline( computeNode );
|
|
|
+ if ( previousPipeline ) {
|
|
|
+
|
|
|
+ previousPipeline.usedTimes --;
|
|
|
+ previousPipeline.computeProgram.usedTimes --;
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
// get shader
|
|
|
|
|
@@ -45,7 +50,7 @@ class Pipelines extends DataMap {
|
|
|
|
|
|
if ( stageCompute === undefined ) {
|
|
|
|
|
|
- if ( previousPipeline ) this._releaseProgram( previousPipeline.computeShader );
|
|
|
+ if ( previousPipeline && previousPipeline.computeProgram.usedTimes === 0 ) this._releaseProgram( previousPipeline.computeProgram );
|
|
|
|
|
|
stageCompute = new ProgrammableStage( nodeBuilder.computeShader, 'compute' );
|
|
|
this.programs.compute.set( nodeBuilder.computeShader, stageCompute );
|
|
@@ -56,7 +61,17 @@ class Pipelines extends DataMap {
|
|
|
|
|
|
// determine compute pipeline
|
|
|
|
|
|
- const pipeline = this._getComputePipeline( stageCompute );
|
|
|
+ const cacheKey = this._getComputeCacheKey( computeNode, stageCompute );
|
|
|
+
|
|
|
+ let pipeline = this.caches.get( cacheKey );
|
|
|
+
|
|
|
+ if ( pipeline === undefined ) {
|
|
|
+
|
|
|
+ if ( previousPipeline && previousPipeline.usedTimes === 0 ) this._releasePipeline( computeNode );
|
|
|
+
|
|
|
+ pipeline = this._getComputePipeline( computeNode, stageCompute, cacheKey );
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
// keep track of all used times
|
|
|
|
|
@@ -65,6 +80,7 @@ class Pipelines extends DataMap {
|
|
|
|
|
|
//
|
|
|
|
|
|
+ data.version = computeNode.version;
|
|
|
data.pipeline = pipeline;
|
|
|
|
|
|
}
|
|
@@ -79,11 +95,17 @@ class Pipelines extends DataMap {
|
|
|
|
|
|
const data = this.get( renderObject );
|
|
|
|
|
|
- if ( this._needsUpdate( renderObject ) ) {
|
|
|
+ if ( this._needsRenderUpdate( renderObject ) ) {
|
|
|
|
|
|
- // release previous cache
|
|
|
+ const previousPipeline = data.pipeline;
|
|
|
|
|
|
- const previousPipeline = this._releasePipeline( renderObject );
|
|
|
+ if ( previousPipeline ) {
|
|
|
+
|
|
|
+ previousPipeline.usedTimes --;
|
|
|
+ previousPipeline.vertexProgram.usedTimes --;
|
|
|
+ previousPipeline.fragmentProgram.usedTimes --;
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
// get shader
|
|
|
|
|
@@ -95,7 +117,7 @@ class Pipelines extends DataMap {
|
|
|
|
|
|
if ( stageVertex === undefined ) {
|
|
|
|
|
|
- if ( previousPipeline ) this._releaseProgram( previousPipeline.vertexProgram );
|
|
|
+ if ( previousPipeline && previousPipeline.vertexProgram.usedTimes === 0 ) this._releaseProgram( previousPipeline.vertexProgram );
|
|
|
|
|
|
stageVertex = new ProgrammableStage( nodeBuilder.vertexShader, 'vertex' );
|
|
|
this.programs.vertex.set( nodeBuilder.vertexShader, stageVertex );
|
|
@@ -108,7 +130,7 @@ class Pipelines extends DataMap {
|
|
|
|
|
|
if ( stageFragment === undefined ) {
|
|
|
|
|
|
- if ( previousPipeline ) this._releaseProgram( previousPipeline.fragmentShader );
|
|
|
+ if ( previousPipeline && previousPipeline.fragmentProgram.usedTimes === 0 ) this._releaseProgram( previousPipeline.fragmentProgram );
|
|
|
|
|
|
stageFragment = new ProgrammableStage( nodeBuilder.fragmentShader, 'fragment' );
|
|
|
this.programs.fragment.set( nodeBuilder.fragmentShader, stageFragment );
|
|
@@ -119,7 +141,21 @@ class Pipelines extends DataMap {
|
|
|
|
|
|
// determine render pipeline
|
|
|
|
|
|
- const pipeline = this._getRenderPipeline( renderObject, stageVertex, stageFragment );
|
|
|
+ const cacheKey = this._getRenderCacheKey( renderObject, stageVertex, stageFragment );
|
|
|
+
|
|
|
+ let pipeline = this.caches.get( cacheKey );
|
|
|
+
|
|
|
+ if ( pipeline === undefined ) {
|
|
|
+
|
|
|
+ if ( previousPipeline && previousPipeline.usedTimes === 0 ) this._releasePipeline( previousPipeline );
|
|
|
+
|
|
|
+ pipeline = this._getRenderPipeline( renderObject, stageVertex, stageFragment, cacheKey );
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ renderObject.pipeline = pipeline;
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
// keep track of all used times
|
|
|
|
|
@@ -139,18 +175,31 @@ class Pipelines extends DataMap {
|
|
|
|
|
|
delete( object ) {
|
|
|
|
|
|
- const pipeline = this._releasePipeline( object );
|
|
|
+ const pipeline = this.get( object ).pipeline;
|
|
|
+
|
|
|
+ if ( pipeline ) {
|
|
|
|
|
|
- if ( pipeline && pipeline.usedTimes === 0 ) {
|
|
|
+ // pipeline
|
|
|
+
|
|
|
+ pipeline.usedTimes --;
|
|
|
+
|
|
|
+ if ( pipeline.usedTimes === 0 ) this._releasePipeline( pipeline );
|
|
|
+
|
|
|
+ // programs
|
|
|
|
|
|
if ( pipeline.isComputePipeline ) {
|
|
|
|
|
|
- this._releaseProgram( pipeline.computeProgram );
|
|
|
+ pipeline.computeProgram.usedTimes --;
|
|
|
+
|
|
|
+ if ( pipeline.computeProgram.usedTimes === 0 ) this._releaseProgram( pipeline.computeProgram );
|
|
|
|
|
|
} else {
|
|
|
|
|
|
- this._releaseProgram( pipeline.vertexProgram );
|
|
|
- this._releaseProgram( pipeline.fragmentProgram );
|
|
|
+ pipeline.fragmentProgram.usedTimes --;
|
|
|
+ pipeline.vertexProgram.usedTimes --;
|
|
|
+
|
|
|
+ if ( pipeline.vertexProgram.usedTimes === 0 ) this._releaseProgram( pipeline.vertexProgram );
|
|
|
+ if ( pipeline.fragmentProgram.usedTimes === 0 ) this._releaseProgram( pipeline.fragmentProgram );
|
|
|
|
|
|
}
|
|
|
|
|
@@ -173,11 +222,11 @@ class Pipelines extends DataMap {
|
|
|
|
|
|
}
|
|
|
|
|
|
- _getComputePipeline( stageCompute ) {
|
|
|
+ _getComputePipeline( computeNode, stageCompute, cacheKey ) {
|
|
|
|
|
|
// check for existing pipeline
|
|
|
|
|
|
- const cacheKey = 'compute:' + stageCompute.id;
|
|
|
+ cacheKey = cacheKey || this._getComputeCacheKey( computeNode, stageCompute );
|
|
|
|
|
|
let pipeline = this.caches.get( cacheKey );
|
|
|
|
|
@@ -195,11 +244,11 @@ class Pipelines extends DataMap {
|
|
|
|
|
|
}
|
|
|
|
|
|
- _getRenderPipeline( renderObject, stageVertex, stageFragment ) {
|
|
|
+ _getRenderPipeline( renderObject, stageVertex, stageFragment, cacheKey ) {
|
|
|
|
|
|
// check for existing pipeline
|
|
|
|
|
|
- const cacheKey = this._getRenderCacheKey( renderObject, stageVertex, stageFragment );
|
|
|
+ cacheKey = cacheKey || this._getRenderCacheKey( renderObject, stageVertex, stageFragment );
|
|
|
|
|
|
let pipeline = this.caches.get( cacheKey );
|
|
|
|
|
@@ -213,15 +262,15 @@ class Pipelines extends DataMap {
|
|
|
|
|
|
this.backend.createRenderPipeline( renderObject );
|
|
|
|
|
|
- } else {
|
|
|
+ }
|
|
|
|
|
|
- // assign a shared pipeline to renderObject
|
|
|
+ return pipeline;
|
|
|
|
|
|
- renderObject.pipeline = pipeline;
|
|
|
+ }
|
|
|
|
|
|
- }
|
|
|
+ _getComputeCacheKey( computeNode, stageCompute ) {
|
|
|
|
|
|
- return pipeline;
|
|
|
+ return 'compute' + computeNode.id + stageCompute.id;
|
|
|
|
|
|
}
|
|
|
|
|
@@ -247,36 +296,30 @@ class Pipelines extends DataMap {
|
|
|
|
|
|
}
|
|
|
|
|
|
- _releasePipeline( object ) {
|
|
|
+ _releasePipeline( pipeline ) {
|
|
|
|
|
|
- const pipeline = this.get( object ).pipeline;
|
|
|
-
|
|
|
- //this.bindings.delete( object );
|
|
|
+ this.caches.delete( pipeline.cacheKey );
|
|
|
|
|
|
- if ( pipeline && -- pipeline.usedTimes === 0 ) {
|
|
|
+ }
|
|
|
|
|
|
- this.caches.delete( pipeline.cacheKey );
|
|
|
+ _releaseProgram( program ) {
|
|
|
|
|
|
- }
|
|
|
+ const code = program.code;
|
|
|
+ const stage = program.stage;
|
|
|
|
|
|
- return pipeline;
|
|
|
+ this.programs[ stage ].delete( code );
|
|
|
|
|
|
}
|
|
|
|
|
|
- _releaseProgram( program ) {
|
|
|
-
|
|
|
- if ( -- program.usedTimes === 0 ) {
|
|
|
-
|
|
|
- const code = program.code;
|
|
|
- const stage = program.stage;
|
|
|
+ _needsComputeUpdate( computeNode ) {
|
|
|
|
|
|
- this.programs[ stage ].delete( code );
|
|
|
+ const data = this.get( computeNode );
|
|
|
|
|
|
- }
|
|
|
+ return data.pipeline === undefined || data.version !== computeNode.version;
|
|
|
|
|
|
}
|
|
|
|
|
|
- _needsUpdate( renderObject ) {
|
|
|
+ _needsRenderUpdate( renderObject ) {
|
|
|
|
|
|
const data = this.get( renderObject );
|
|
|
const material = renderObject.material;
|
|
@@ -312,7 +355,7 @@ class Pipelines extends DataMap {
|
|
|
|
|
|
}
|
|
|
|
|
|
- return needsUpdate || data.pipeline !== undefined;
|
|
|
+ return needsUpdate || data.pipeline === undefined;
|
|
|
|
|
|
}
|
|
|
|