nx_gpu_timestamp_lib.nx source
↩ module page · 37 lines · 1595 B
1// Lossless WebGPU timestamp transport: canonical decimal uint64, two unsigned 32-bit limbs.
2// Values are raw device-clock nanoseconds, never host-clock timestamps or GPU submission time.
3const GTS_LIMB_BASE: i64 = 4294967296
4const GTS_LIMB_MAX: i64 = GTS_LIMB_BASE-1
5const GTS_DECIMAL_MAX: i64 = 20
6// Caller supplies two words. Invalid input leaves them unchanged.
7func gts_u64(b: *u8, n: i64, out: *i64) -> i64 {
8 if n<1 || n>GTS_DECIMAL_MAX { return 0 }
9 if n>1 { if b[0]==48 as u8 { return 0 } }
10 var lo: i64=0; var hi: i64=0; var i: i64=0
11 while i<n {
12 let c: i64=b[i] as i64
13 if c<48 || c>57 { return 0 }
14 let next: i64=lo*10+c-48
15 hi=hi*10+next/GTS_LIMB_BASE
16 lo=next%GTS_LIMB_BASE
17 if hi>GTS_LIMB_MAX { return 0 }
18 i=i+1
19 }
20 out[0]=lo; out[1]=hi; return 1
21}
22// Caller owns six scratch words. All three decimal inputs must be canonical uint64.
23// Reversed intervals are refused; no assumption about timestamp counter wrapping is made.
24func gts_interval(start: *u8, sn: i64, finish: *u8, fn: i64, duration: *u8, dn: i64, scratch: *i64) -> i64 {
25 let endpair: *i64=((scratch as i64)+16) as *i64
26 let diffpair: *i64=((scratch as i64)+32) as *i64
27 if gts_u64(start,sn,scratch)==0 { return 0 }
28 if gts_u64(finish,fn,endpair)==0 { return 0 }
29 if gts_u64(duration,dn,diffpair)==0 { return 0 }
30 if endpair[1]<scratch[1] { return 0 }
31 if endpair[1]==scratch[1] { if endpair[0]<scratch[0] { return 0 } }
32 var dlo: i64=endpair[0]-scratch[0]
33 var dhi: i64=endpair[1]-scratch[1]
34 if dlo<0 { dlo=dlo+GTS_LIMB_BASE; dhi=dhi-1 }
35 if dlo!=diffpair[0] || dhi!=diffpair[1] { return 0 }
36 return 1
37}