| basic |
const a = 1;
return a;
|
[..., i32, 'constant'] |
[..., i32, snippet(1, i32, 'constant')]
|
It is required for the d.ref case mentioned above
|
const a = 1;
const b = a;
return b;
|
[..., i32, 'constant'] |
[..., i32, snippet(1, i32, 'constant')]
|
Note that b 'references' a in the code, but the origin points
to the highest snippet in the chain.
|
fn([i32])((a) => return a); |
[..., i32, 'argument'] |
[..., i32, 'argument'] |
Non-ref arguments are copied, so a is the highest origin
|
fn([i32])((a) => {
const b = a;
return b;
})
|
[..., i32, 'runtime'] |
[..., i32, snippet(a, i32, 'argument')] |
|
return getOne(); |
[..., i32, 'runtime'] |
[..., i32, 'runtime'] |
Here, we can potentially run into issue with getById, calls should be represented by separate snippets
|
const b = getOne();
return b;
|
[..., i32, 'runtime'] |
[..., i32, snippet('getOne()', i32, 'runtime')]
|
|
return vec2i(7);
|
[..., vec2i, 'constant']
|
[..., vec2i, 'constant']
|
|
const a = vec2i(7);
return a;
|
[..., vec2i, 'this-function']
|
[..., vec2i, snippet(vec2i(7), vec2i, 'constant')]
|
|
const a = vec2i(7);
const b = a;
return b;
|
[..., iptr<function,vec2i,rw>, 'this-function']
|
[..., iptr<function,vec2i,rw>, snippet(vec2i(7), vec2i, 'constant')]
|
Note, how datatype has changed |
fn([vec2i])((a) => return a); |
[..., vec2i, 'argument'] |
[..., vec2i, 'argument'] |
Uninterrupted flow :) |
fn([vec2i])((a) => {
const b = a;
return b;
})
|
[..., vec2i, 'argument'] |
[..., vec2i, snippet(a, vec2i, 'argument')]
|
Implicit pointer btw, but currently cannot take pointer to te argument. TODO: carefully handle this case
|
fn([vec2i])((a) => return a.x); |
[..., i32, 'argument'] |
[..., i32, 'argument'] |
Uninterrupted flow :) |
fn([vec2i])((a) => {
const b = a.x;
return b;
})
|
[..., i32, 'runtime'] |
[..., i32, snippet('a.x', i32, 'argument')] |
Comparing to the above flow, origin has changed. Maybe it should remain 'runtime'
|
return getV(); |
[..., vec3f, 'runtime'] |
[..., vec3f, 'runtime'] |
|
const b = getV();
return b;
|
[..., vec3f, 'this-function']
|
[..., vec3f, snippet('getV()', vec3f, 'runtime')]
|
Cannot really put 'this-function' origin here, what if we
assign the result to a buffer?
|
| uniform |
return buf.$; |
[..., f32, 'runtime'] |
[..., f32, 'runtime'] |
Buffer element is naturally ephemeral |
const b = buf.$;
return b;
|
[..., f32, 'runtime'] |
[..., f32, snippet('buf', f32, 'runtime')] |
On the contrary to the function call, we should distribute only
1 reference to buffer access snippet
|
return buf.$; |
[..., vec3f, 'uniform'] |
[..., vec3f, 'uniform'] |
Buffer element is NOT naturally ephemeral |
const b = buf.$;
return b;
|
[..., iptr<uniform,vec3f,r>, 'uniform']
|
[..., iptr<uniform,vec3f,r>, snippet('buf', vec3f, 'uniform')]
|
|
| readonly |
return buf.$; |
[..., f32, 'runtime'] |
[..., f32, 'runtime'] |
|
const b = buf.$;
return b;
|
[..., f32, 'runtime'] |
[..., f32, snippet('buf', f32, 'runtime')] |
|
return buf.$; |
[..., vec3f, 'readonly'] |
[..., vec3f, 'readonly'] |
|
const b = buf.$;
return b;
|
[..., iptr<storage,vec3f,r>, 'readonly']
|
[..., iptr<storage,vec3f,r>, snippet('buf', vec3f, 'readonly')]
|
|
| mutable |
return buf.$; |
[..., f32, 'runtime'] |
[..., f32, 'runtime'] |
|
const b = buf.$;
return b;
|
[..., f32, 'runtime'] |
[..., f32, snippet('buf', f32, 'runtime')] |
|
return buf.$; |
[..., vec3f, 'mutable'] |
[..., vec3f, 'mutable'] |
|
const b = buf.$;
return b;
|
[..., iptr<storage,vec3f,rw>, 'mutable']
|
[..., iptr<storage,vec3f,rw>, snippet('buf', vec3f, 'mutable')]
|
|
| private |
return pv.$; |
[..., f32, 'runtime'] |
[..., f32, 'runtime'] |
|
const b = pv.$;
return b;
|
[..., f32, 'runtime'] |
[..., f32, snippet('pv', f32, 'runtime')] |
|
return pv.$; |
[..., vec3f, 'private'] |
[..., vec3f, 'private'] |
|
const b = pv.$;
return b;
|
[..., iptr<private,vec3f,rw>, 'private']
|
[..., iptr<private,vec3f,rw>, snippet('pv', vec3f, 'private')]
|
|
| workgroup |
return wgv.$; |
[..., f32, 'runtime'] |
[..., f32, 'runtime'] |
|
const b = wgv.$;
return b;
|
[..., f32, 'runtime'] |
[..., f32, snippet('wgv', f32, 'runtime')] |
|
return wgv.$; |
[..., vec3f, 'workgroup'] |
[..., vec3f, 'workgroup'] |
|
const b = wgv.$;
return b;
|
[..., iptr<workgroup,vec3f,rw>, 'workgroup']
|
[..., iptr<workgroup,vec3f,rw>, snippet('wgv', vec3f, 'workgroup')]
|
|
| handle |
return layout.$.s; |
[..., sampler, 'handle'] |
[..., sampler, 'handle'] |
For now, you cannot assign sampler or texture to a variable
|
| tgpu.const |
return c.$; |
[..., u32, 'constant'] |
[..., u32, 'constant'] |
|
const b = c.$;
return b;
|
[..., u32, 'constant'] |
[..., u32, snippet('c', u32, 'constant')] |
|
return c.$; |
[..., vec3f, 'constant-tgpu-const-ref']
|
[..., vec3f, 'constant-tgpu-const-ref']
|
|
const b = c.$;
return b;
|
[..., vec3f, 'constant-tgpu-const-ref']
|
[..., vec3f, snippet('c', vec3f, 'constant-tgpu-const-ref')]
|
|
fn([i32])((i) => return arr.$[i]); |
[..., f32, 'runtime'] |
[..., f32, 'runtime'] |
|
fn([i32])((i) => {
const b = arr.$[i];
return b;
})
|
[..., f32, 'runtime'] |
[..., f32, snippet('arr[i]', f32, 'runtime')]
|
|
fn([i32])((i) => return arr.$[i]); |
[..., vec3f, 'runtime-tgpu-const-ref']
|
[..., vec3f, 'runtime-tgpu-const-ref']
|
|
fn([i32])((i) => {
const b = arr.$[i];
return b;
})
|
[..., vec3f, 'runtime-tgpu-const-ref']
|
[..., vec3f, snippet('arr[i]', vec3f, 'runtime-tgpu-const-ref')]
|
|
| struct |
return buf.$.count; |
[..., u32, 'runtime'] |
[..., u32, 'runtime'] |
|
const b = buf.$.count;
return b;
|
[..., u32, 'runtime'] |
[..., u32, snippet('buf.count', u32, 'runtime')]
|
Access to struct should be distributed as reference to one unique snippet
|
return buf.$.pos; |
[..., vec3f, 'uniform'] |
[..., vec3f, 'uniform'] |
|
const b = buf.$.pos;
return b;
|
[..., iptr<uniform,vec3f,r>, 'uniform']
|
[..., iptr<uniform,vec3f,r>, snippet('buf.$.pos', vec3f, 'uniform')]
|
|
| swizzle |
fn([vec3f])((v) => return v.x); |
[..., f32, 'argument'] |
[..., f32, 'argument'] |
|
fn([vec3f])((v) => {
const b = v.x;
return b;
})
|
[..., f32, 'runtime'] |
[..., f32, snippet('v.x', f32, 'runtime')] |
|
fn([vec3f])((v) => return v.xy); |
[..., vec2f, 'runtime'] |
[..., vec2f, 'runtime'] |
|
fn([vec3f])((v) => {
const b = v.xy;
return b;
})
|
[..., vec2f, 'this-function']
|
[..., vec2f, snippet('v.xy', vec2f, 'runtime')]
|
|
| d.ref |
const b = d.ref(u32(0));
return b;
|
[..., ptr<function,u32,rw>, 'function']
|
[..., ptr<function,u32,rw>, snippet(u32(0), u32, 'constant')]
|
Not sure about that |
const b = d.ref(vec2f());
return b;
|
[..., ptr<function,vec2f,rw>, 'function']
|
[..., ptr<function,vec2f,rw>, snippet(vec2f(0), vec2f, 'constant')]
|
|
|
mixed origins in complex types
|
return vec4f(7).xz; |
[..., vec2f, 'constant'] |
[..., vec2f, 'constant'] |
|
const b = vec4f(7).xz;
return b;
|
[..., vec2f, 'this-function'] |
[..., vec2f, snippet(vec4f(7).xz, vec2f, 'constant')]
|
|
return vec4f(buf.$, 1).xw; |
[..., vec2f, 'runtime'] |
[..., vec2f, 'runtime']
|
|
const b = vec4f(buf.$, 1).xw;
return b;
|
[..., vec2f, 'this-function'] |
[..., vec2f, snippet(vec4f(buf.$, 1), vec2f, 'runtime')]
|
Constructors perform deep copy :)) |
const a = Boid();
return a.pos;
|
[..., vec2f, 'this-function'] |
[..., vec2f, 'this-function'] |
Not sure about that because there is nothing to be referenced
|
const a = Boid();
const b = a.pos;
return b;
|
[..., iptr<function,vec2f,rw>, 'this-function']
|
[..., iptr<function,vec2f,rw>, snippet(a.pos, vec2f, 'this-function')]
|
|
const a = Boid({ pos: buf.$, ... });
return a.pos;
|
[..., vec2f, 'this-function'] |
[..., vec2f, 'this-function'] |
Again, constructors perform deep copy |
const a = Boid({ pos: buf.$, ... });
const b = a.pos;
return b;
|
[..., iptr<function,vec2f,rw>, 'this-function']
|
[..., iptr<function,vec2f,rw>, snippet(a.pos, vec2f, 'this-function')]
|
|
The purpose of this issue is to introduce concept of the origin chain. It should help with forbidding the following
and would make consumption tracking easier.
Origin chaining is allowing the snippet to be origin field value.
If
originfield is a snippet then it should reference the highest snippet in a chain (snippet withorigin: Origin) .This table shows current and future behavior of snippets (we examine returned value):
fn([i32])((a) => { const b = a; return b; })[..., i32, snippet('getOne()', i32, 'runtime')]fn([vec2i])((a) => { const b = a; return b; })fn([vec2i])((a) => { const b = a.x; return b; })[..., i32, snippet('a.x', i32, 'argument')][..., vec3f, snippet('getV()', vec3f, 'runtime')][..., f32, snippet('buf', f32, 'runtime')][..., iptr<uniform,vec3f,r>, snippet('buf', vec3f, 'uniform')][..., f32, snippet('buf', f32, 'runtime')][..., iptr<storage,vec3f,r>, snippet('buf', vec3f, 'readonly')][..., f32, snippet('buf', f32, 'runtime')][..., iptr<storage,vec3f,rw>, snippet('buf', vec3f, 'mutable')][..., f32, snippet('pv', f32, 'runtime')][..., iptr<private,vec3f,rw>, snippet('pv', vec3f, 'private')][..., f32, snippet('wgv', f32, 'runtime')][..., iptr<workgroup,vec3f,rw>, snippet('wgv', vec3f, 'workgroup')][..., u32, snippet('c', u32, 'constant')][..., vec3f, snippet('c', vec3f, 'constant-tgpu-const-ref')]fn([i32])((i) => { const b = arr.$[i]; return b; })[..., f32, snippet('arr[i]', f32, 'runtime')]fn([i32])((i) => { const b = arr.$[i]; return b; })[..., vec3f, snippet('arr[i]', vec3f, 'runtime-tgpu-const-ref')][..., u32, snippet('buf.count', u32, 'runtime')][..., iptr<uniform,vec3f,r>, snippet('buf.$.pos', vec3f, 'uniform')]fn([vec3f])((v) => { const b = v.x; return b; })[..., f32, snippet('v.x', f32, 'runtime')]fn([vec3f])((v) => { const b = v.xy; return b; })[..., vec2f, snippet('v.xy', vec2f, 'runtime')]const a = Boid({ pos: buf.$, ... }); return a.pos;const a = Boid({ pos: buf.$, ... }); const b = a.pos; return b;TODO: