Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/typegpu/src/data/dataTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@ export function undecorate(data: BaseData): BaseData {
return data;
}

export function unptr(data: BaseData): BaseData;
export function unptr(data: BaseData | UnknownData): BaseData | UnknownData;
export function unptr(data: BaseData | UnknownData): BaseData | UnknownData {
if (wgsl.isPtr(data)) {
return data.inner;
Expand Down
44 changes: 31 additions & 13 deletions packages/typegpu/src/tgsl/consoleLog/logGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type { TgpuRoot } from '../../core/root/rootTypes.ts';
import { shaderStageSlot } from '../../core/slot/internalSlots.ts';
import { arrayOf } from '../../data/array.ts';
import { atomic } from '../../data/atomic.ts';
import { UnknownData } from '../../data/dataTypes.ts';
import { UnknownData, unptr } from '../../data/dataTypes.ts';
import { u32 } from '../../data/numeric.ts';
import { snip, type Snippet } from '../../data/snippet.ts';
import { struct } from '../../data/struct.ts';
Expand All @@ -15,8 +15,10 @@ import {
Void,
type WgslArray,
} from '../../data/wgslTypes.ts';
import { invariant } from '../../errors.ts';
import { $internal } from '../../shared/symbols.ts';
import { concretizeSnippets, type GenerationCtx } from '../generationHelpers.ts';
import { convertToCommonType } from '../conversion.ts';
import { concretizeSnippet, type GenerationCtx } from '../generationHelpers.ts';
import { createLoggingFunction } from './serializers.ts';
import {
type LogGenerator,
Expand Down Expand Up @@ -87,30 +89,46 @@ export class LogGeneratorImpl implements LogGenerator {
return fallbackSnippet;
}

const concreteArgs = concretizeSnippets(args);
const id = this.#firstUnusedId++;

const nonStringArgs = concreteArgs.filter((e) => e.dataType !== UnknownData);
const concreteArgsWithStrings = args
.map((arg) => {
if (typeof arg.dataType === 'symbol') {
return arg;
}
const converted = convertToCommonType(ctx, [arg], [unptr(arg.dataType)])?.[0];
invariant(
converted,
`Internal error. Expected type ${arg.dataType} to be convertible to ${unptr(arg.dataType)}`,
);
return converted;
})
.map(concretizeSnippet);
Comment thread
aleksanderkatan marked this conversation as resolved.

const concreteArgs = concreteArgsWithStrings.filter((arg) => typeof arg.dataType !== 'symbol');

const logFn = createLoggingFunction(
id,
nonStringArgs.map((e) => e.dataType as AnyWgslData),
concreteArgs.map((e) => e.dataType as AnyWgslData),
this.#dataBuffer,
this.#indexBuffer,
this.#options,
);

const argTypes = concreteArgs.map((e) =>
e.dataType === UnknownData ? (e.value as string) : (e.dataType as AnyWgslData),
);

this.#logIdToMeta.set(id, { op: op as SupportedLogOps, argTypes });

return snip(
stitch`${ctx.resolve(logFn).value}(${nonStringArgs})`,
const functionSnippet = snip(
stitch`${ctx.resolve(logFn).value}(${concreteArgs})`,
Void,
/* origin */ 'runtime',
);

this.#logIdToMeta.set(id, {
op: op as SupportedLogOps,
argTypes: concreteArgsWithStrings.map((e) =>
e?.dataType === UnknownData ? (e?.value as string) : (e?.dataType as AnyWgslData),
),
});

return functionSnippet;
}

get logResources(): LogResources | undefined {
Expand Down
5 changes: 1 addition & 4 deletions packages/typegpu/src/tgsl/wgslGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -772,10 +772,7 @@ ${this.ctx.pre}}`;
);
}
// Taking care of abstract numerics and implicit pointers
accessed = structType.provideProp(
key,
unptr(concretize(expr.dataType)) as wgsl.BaseData,
);
accessed = structType.provideProp(key, unptr(concretize(expr.dataType)));
}

return [accessed.prop, expr];
Expand Down
66 changes: 66 additions & 0 deletions packages/typegpu/tests/tgsl/consoleLog.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,72 @@ describe('wgslGenerator with console.log', () => {
expect(consoleWarnSpy).toHaveBeenCalledWith("Unsupported log method 'trace'.");
expect(consoleWarnSpy).toHaveBeenCalledTimes(1);
});

it('works with implicit pointers', ({ root }) => {
const myUniform = root.createUniform(d.vec2f);
const myPipeline = root.createGuardedComputePipeline((x) => {
'use gpu';
const v = myUniform.$;
console.log(v);
});

expect(tgpu.resolve([myPipeline.pipeline])).toMatchInlineSnapshot(`
"@group(0) @binding(0) var<uniform> sizeUniform: vec3u;

@group(0) @binding(1) var<uniform> myUniform: vec2f;

@group(0) @binding(2) var<storage, read_write> indexBuffer: atomic<u32>;

struct SerializedLogData {
id: u32,
serializedData: array<u32, 63>,
}

@group(0) @binding(3) var<storage, read_write> dataBuffer: array<SerializedLogData, 64>;

var<private> dataBlockIndex: u32;

var<private> dataByteIndex: u32;

fn nextByteIndex() -> u32 {
let i = dataByteIndex;
dataByteIndex = dataByteIndex + 1u;
return i;
}

fn serializeVec2f(v: vec2f) {
dataBuffer[dataBlockIndex].serializedData[nextByteIndex()] = bitcast<u32>(v.x);
dataBuffer[dataBlockIndex].serializedData[nextByteIndex()] = bitcast<u32>(v.y);
}

fn log1serializer(_arg_0: vec2f) {
serializeVec2f(_arg_0);
}

fn log1(_arg_0: vec2f) {
dataBlockIndex = atomicAdd(&indexBuffer, 1);
if (dataBlockIndex >= 64) {
return;
}
dataBuffer[dataBlockIndex].id = 1;
dataByteIndex = 0;

log1serializer(_arg_0);
}

fn wrappedCallback(x: u32, _arg_1: u32, _arg_2: u32) {
let v = (&myUniform);
log1((*v));
}

@compute @workgroup_size(256, 1, 1) fn mainCompute(@builtin(global_invocation_id) id: vec3u) {
if (any(id >= sizeUniform)) {
return;
}
wrappedCallback(id.x, id.y, id.z);
}"
`);
});
});

describe('deserializeAndStringify', () => {
Expand Down
Loading