Skip to content

Commit

Permalink
async texture fetch
Browse files Browse the repository at this point in the history
  • Loading branch information
znah committed Sep 13, 2023
1 parent 4da7b36 commit cd26e6d
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 3 deletions.
4 changes: 2 additions & 2 deletions demo/FancyLenia.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,14 @@ class FancyLenia extends ParticleLenia {
float a = normal.z*0.7+0.3;
FOut = vec4(vec3(1.0-a*a*0.75), 1.0);`});

this.meanEnergy = glsl({state:state[0], FP:`
glsl({state:state[0], FP:`
ivec2 sz = state_size();
float E = 0.0;
for (int y=0; y<sz.y; ++y)
for (int x=0; x<sz.x; ++x) {
E += state(ivec2(x,y)).w;
}
FOut.x = E / float(sz.x*sz.y);`},
{size:[1,1], format:'r32f', tag:'meanE'}).readSync()[0]
{size:[1,1], format:'r32f', tag:'meanE'}).read([],d=>this.meanEnergy=d[0]);
}
}
3 changes: 3 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Changelog

### 2023-09-12
* Async texture fetch support (`target.read(box, data=>{...})`)

### 2023-09-07
* Samplers support (see [TextureSamplers](https://google.github.io/swissgl/#TextureSamplers) demo)

Expand Down
63 changes: 62 additions & 1 deletion swissgl.js
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,9 @@ function guessUniforms(params) {
vec${D} ${name}_step() {return 1.0/vec${D}(${name}_size());}`;
} else if (typeof v === 'number') {
s=`uniform float ${name};`
} else if (v.length in len2type) {
} else if (typeof v === 'boolean') {
s=`uniform bool ${name};`
} else if (v.length in len2type) {
s=`uniform ${len2type[v.length]} ${name};`
}
if (s) uni.push(s);
Expand Down Expand Up @@ -479,10 +481,69 @@ class TextureTarget extends TextureSampler {
gl.readPixels(x, y, w, h, glformat, type, buf);
return (buf.length == n) ? buf : buf.subarray(0, n);
}
_bindAsyncBuffer(n) {
const {gl} = this;
const {CpuArray} = this.formatInfo;
if (!this.async) {this.async = {all:new Set(), queue:[]};}
if (this.async.queue.length == 0) {
const newBuf = {gpu: gl.createBuffer(), cpu:null};
this.async.queue.push(newBuf);
this.async.all.add(newBuf);
}
const buf = this.async.queue.shift();
if (this.async.queue.length > 2) {
this._deleteAsyncBuf(this.async.queue.pop());
}
gl.bindBuffer(gl.PIXEL_PACK_BUFFER, buf.gpu);
if (!buf.cpu || buf.cpu.length < n) {
buf.cpu = new CpuArray(n);
gl.bufferData(gl.PIXEL_PACK_BUFFER, buf.cpu.byteLength, gl.STREAM_READ);
console.log(`created/resized async buffer "${this.tag}":`, buf);
}
return buf;
}
_deleteAsyncBuf(buf) {
this.gl.deleteBuffer(buf.gpu);
delete buf.cpu; delete buf.gpu;
this.async.all.delete(buf);
}
// https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#use_non-blocking_async_data_readback
read(box, callback, target) {
const {gl} = this;
const {chn, glformat, type} = this.formatInfo;
const [x, y, w, h] = (box && box.length) ? box : [0, 0, ...this.size];
const n = w*h*chn;
this.bind(gl);
const buf = this. _bindAsyncBuffer(n);
gl.readPixels(x, y, w, h, glformat, type, 0);
gl.bindBuffer(gl.PIXEL_PACK_BUFFER, null);
const sync = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0);
gl.flush();
target = target || buf.cpu;
target = target.length == n ? target : target.subarray(0, n);
const test = ()=>{
if (!buf.gpu) return; // check that the buffer is not deleted
const res = gl.clientWaitSync(sync, 0, 0);
if (res === gl.TIMEOUT_EXPIRED) { setTimeout(test, 1 /*ms*/); return; }
if (res === gl.WAIT_FAILED) {
console.log(`async read of ${this.tag} failed`);
} else {
gl.bindBuffer(gl.PIXEL_PACK_BUFFER, buf.gpu);
gl.getBufferSubData(gl.PIXEL_PACK_BUFFER, 0 /*srcOffset*/,
target, 0 /*dstOffset*/, n /*length*/);
gl.bindBuffer(gl.PIXEL_PACK_BUFFER, null);
callback(target);
}
gl.deleteSync(sync);
this.async.queue.push(buf);
}
test();
}
free() {
const gl = this.gl;
if (this.depth) this.depth.free();
if (this.fbo) gl.deleteFramebuffer(this.fbo);
if (this.async) this.async.all.forEach(buf=>this._deleteAsyncBuf(buf));
gl.deleteTexture(this.handle);
}
}
Expand Down

0 comments on commit cd26e6d

Please sign in to comment.