function copy2DTexture(precision, mode) { const gpu = new GPU({ mode }); function makeTexture() { return (gpu.createKernel(function() { return this.thread.x + (this.thread.y * this.output.x); }, { output: [5, 5], pipeline: true, precision }))(); } const texture = makeTexture(); const clone = texture.clone(); assert.notEqual(texture, clone); assert.equal(texture.texture, clone.texture); assert.deepEqual(texture.toArray(), clone.toArray()); gpu.destroy(); }
function testMutableLeak(mode) { const gpu = new GPU({ mode }); const kernel = gpu.createKernel(function() { return 1; }, { output: [1], pipeline: true }); kernel.build(); const cloneTextureSpy = sinon.spy(kernel.texture.constructor.prototype, 'beforeMutate'); const texture1 = kernel(); const texture2 = kernel(); assert.equal(cloneTextureSpy.callCount, 0); assert.equal(texture1.texture._refs, 1); assert.ok(texture1 === texture2); cloneTextureSpy.restore(); gpu.destroy(); }
function copy1DTexture(precision, mode) { const gpu = new GPU({ mode }); function makeTexture() { return (gpu.createKernel(function() { return this.thread.x; }, { output: [5], pipeline: true, precision }))(); } const texture = makeTexture(); const clone = texture.clone(); assert.notEqual(texture, clone); assert.equal(texture.texture, clone.texture); assert.deepEqual(texture.toArray(), clone.toArray()); gpu.destroy(); }
}); const result = kernel(); assert.equal(result.texture._refs, 2); const clone1 = result.clone(); assert.equal(result.texture._refs, 3); const clone2 = result.clone(); assert.equal(result.texture._refs, 4); const clone3 = result.clone(); assert.equal(result.texture._refs, 5); const clone4 = result.clone(); assert.equal(result.texture._refs, 6); const clone5 = result.clone(); assert.equal(result.texture._refs, 7); assert.equal(result.texture._refs, 6); clone2.delete(); assert.equal(result.texture._refs, 5); clone3.delete(); assert.equal(result.texture._refs, 4); clone4.delete(); assert.equal(result.texture._refs, 3); clone5.delete(); assert.equal(result.texture._refs, 2); result.delete(); assert.equal(result.texture._refs, 1); const spy = sinon.spy(kernel.kernel.context, 'deleteTexture'); gpu.destroy() .then(() => { assert.equal(result.texture._refs, 0);
function copy3DTexture(precision, mode) { const gpu = new GPU({ mode }); function makeTexture() { return (gpu.createKernel(function() { return this.thread.x + (this.thread.y * this.output.x) * (this.output.x * this.output.y * this.thread.z); }, { output: [5, 5, 5], pipeline: true, precision }))(); } const texture = makeTexture(); const clone = texture.clone(); assert.notEqual(texture, clone); assert.equal(texture.texture, clone.texture); assert.deepEqual(texture.toArray(), clone.toArray()); gpu.destroy(); }
}); const one = toTexture([1]); assert.equal(one.texture._refs, 2); // one's texture will be used in two places at first, in one and toTexture.texture assert.equal(toTexture.texture.texture, one.texture); // very important, a clone was mode, but not a deep clone assert.notEqual(one, toTexture.texture); const two = toTexture([2]); assert.equal(one.texture._refs, 1); // was tracked on toTexture.texture, and deleted assert.equal(toTexture.texture.texture, two.texture); assert.notEqual(toTexture.texture.texture, one.texture); assert.equal(two.texture._refs, 2); one.delete(); two.delete(); assert.equal(one.texture._refs, 0); assert.equal(two.texture._refs, 1); // still used by toTexture.texture two.delete(); // already deleted assert.equal(two.texture._refs, 1); // still used by toTexture gpu.destroy() .then(() => { assert.equal(two.texture._refs, 0); done(); });