summaryrefslogtreecommitdiff
path: root/cnn_v3/tools/tester.js
diff options
context:
space:
mode:
authorskal <pascal.massimino@gmail.com>2026-03-22 17:47:17 +0100
committerskal <pascal.massimino@gmail.com>2026-03-22 17:47:17 +0100
commit9bca6af775b723dd5bb972f6178516708abf58e2 (patch)
treec179830be9c238ba20daca5b9ff17c6170d671e7 /cnn_v3/tools/tester.js
parent3573654c3a60b8bd7545f4240273ed767699f1ae (diff)
feat(cnn_v3/tools): zoom canvas shows region around clicked texel
Diffstat (limited to 'cnn_v3/tools/tester.js')
-rw-r--r--cnn_v3/tools/tester.js30
1 files changed, 20 insertions, 10 deletions
diff --git a/cnn_v3/tools/tester.js b/cnn_v3/tools/tester.js
index dbc7414..0412cae 100644
--- a/cnn_v3/tools/tester.js
+++ b/cnn_v3/tools/tester.js
@@ -465,7 +465,12 @@ class CNNv3Tester {
const cvs=document.createElement('canvas');
const name=chName(c);
cvs.title=name;
- cvs.onclick=()=>tester.zoomChannel(id,c,name);
+ cvs.onclick=(e)=>{
+ const r=cvs.getBoundingClientRect();
+ const tx=Math.round(e.offsetX/r.width*tex.width);
+ const ty=Math.round(e.offsetY/r.height*tex.height);
+ tester.zoomChannel(id,c,name,tx,ty);
+ };
cell.appendChild(lbl); cell.appendChild(cvs); grid.appendChild(cell);
}
const pl=def.t==='f32'?this.getVizF32():this.getVizU32();
@@ -474,8 +479,8 @@ class CNNv3Tester {
cvs.width=tex.width; cvs.height=tex.height;
const ctx=cvs.getContext('webgpu'); if(!ctx)continue;
try{ctx.configure({device:this.device,format:this.format});}catch(_){continue;}
- const chBuf=this.device.createBuffer({size:4,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST});
- this.device.queue.writeBuffer(chBuf,0,new Uint32Array([c]));
+ const chBuf=this.device.createBuffer({size:16,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST});
+ this.device.queue.writeBuffer(chBuf,0,new Int32Array([c,0,0,0]));
const bg=this.device.createBindGroup({layout:pl.getBindGroupLayout(0),
entries:[{binding:0,resource:tex.createView()},{binding:1,resource:{buffer:chBuf}}]});
const enc=this.device.createCommandEncoder();
@@ -487,13 +492,13 @@ class CNNv3Tester {
await this.device.queue.onSubmittedWorkDone();
}
- zoomChannel(layerId, ch, label) {
+ zoomChannel(layerId, ch, label, clickTx=0, clickTy=0) {
const def = this.vizDefs?.find(d => d.id === layerId);
const tex = this.layerTextures[layerId];
if (!def || !tex || !this.device) return;
const wrap = document.getElementById('chzoomWrap');
const lbl = document.getElementById('chzoomLbl');
- this.activeZoom = {layerId, ch, label};
+ this.activeZoom = {layerId, ch, label, clickTx, clickTy};
lbl.textContent = label;
wrap.style.display = 'flex';
// Wait for layout so clientWidth/clientHeight reflect the flex-distributed size
@@ -506,12 +511,17 @@ class CNNv3Tester {
const scale = Math.min(1, availW / tex.width, availH / tex.height);
dst.width = Math.round(tex.width * scale);
dst.height = Math.round(tex.height * scale);
- // Re-render via WebGPU (WebGPU canvas pixels are not readable by drawImage)
+ // Re-render via WebGPU centered on the clicked texel
+ const ox = clickTx - Math.floor(dst.width / 2);
+ const oy = clickTy - Math.floor(dst.height / 2);
const pl = def.t === 'f32' ? this.getVizF32() : this.getVizU32();
const ctx = dst.getContext('webgpu');
try { ctx.configure({device: this.device, format: this.format}); } catch(_) { return; }
- const chBuf = this.device.createBuffer({size:4, usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST});
- this.device.queue.writeBuffer(chBuf, 0, new Uint32Array([ch]));
+ const uData = new ArrayBuffer(16);
+ const dv = new DataView(uData);
+ dv.setUint32(0, ch, true); dv.setInt32(8, ox, true); dv.setInt32(12, oy, true);
+ const chBuf = this.device.createBuffer({size:16, usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST});
+ this.device.queue.writeBuffer(chBuf, 0, uData);
const bg = this.device.createBindGroup({layout: pl.getBindGroupLayout(0),
entries:[{binding:0, resource:tex.createView()}, {binding:1, resource:{buffer:chBuf}}]});
const enc = this.device.createCommandEncoder();
@@ -525,8 +535,8 @@ class CNNv3Tester {
refreshZoom() {
if (this.activeZoom) {
- const {layerId, ch, label} = this.activeZoom;
- this.zoomChannel(layerId, ch, label);
+ const {layerId, ch, label, clickTx, clickTy} = this.activeZoom;
+ this.zoomChannel(layerId, ch, label, clickTx, clickTy);
}
}