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
9 changes: 5 additions & 4 deletions apps/typegpu-docs/src/content/docs/apis/utils.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ Use an `if` statement for those cases.
TypeGPU exposes two standard-library probes for code that needs to adapt to its execution environment:

- `std.isBeingTranspiled()` tells a direct `'use gpu'` callee whether it is currently being transpiled.
- `std.getTargetShaderLanguage()` returns `'wgsl'` during WGSL resolution and `undefined` otherwise.
- `std.getTargetShaderLanguage()` returns the name of the shader language being generated (usually `'wgsl'`)
if it's called during shader generation, and `undefined` otherwise.

```ts twoslash
import { tgpu, d, std } from 'typegpu';
Expand All @@ -130,9 +131,9 @@ Their behavior in each environment is:
| Environment | `isBeingTranspiled()` | `getTargetShaderLanguage()` |
| --- | --- | --- |
| Normal JavaScript | `false` | `undefined` |
| Direct `'use gpu'` callee being transpiled | `true` | `'wgsl'` |
| Inside `tgpu.comptime` | `false` | `'wgsl'` during resolution; otherwise `undefined` |
| Inside `tgpu.lazy` | `false` | `'wgsl'` |
| Direct `'use gpu'` callee being transpiled | `true` | name of the shader language, e.g. `'wgsl'` |
| Inside `tgpu.comptime` | `false` | during resolution, name of the shader language, e.g. `'wgsl'`; otherwise `undefined` |
| Inside `tgpu.lazy` | `false` | name of the shader language, e.g. `'wgsl'` |
| Inside `tgpu['~unstable'].simulate` | `false` | `undefined` |

These probes are intended for environment-specific implementation choices.
Expand Down
4 changes: 4 additions & 0 deletions packages/typegpu-gl/src/glslGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ export class GlslGenerator extends WgslGenerator {
#functionType: TgpuShaderStage | 'normal' | undefined;
#entryFnState: EntryFnState | undefined;

static {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a reason why declare is omitted in glsl generator?

// prototype properties
declare languageKey: string;

The above code snippet comes from wgsl generator.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because it inherits that property from the WgslGenerator class

GlslGenerator.prototype.languageKey = 'glsl';
}

override typeAnnotation(data: d.BaseData): string {
// For WGSL identity types (scalars, vectors, common matrices), map to GLSL directly.
if (!d.isLooseData(data)) {
Expand Down
17 changes: 16 additions & 1 deletion packages/typegpu-gl/tests/glslGenerator.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { describe, expect, it } from 'vitest';
import { tgpu, d } from 'typegpu';
import { tgpu, d, std } from 'typegpu';
import { glOptions } from '@typegpu/gl';
import { translateWgslTypeToGlsl } from '../src/glslGenerator.ts';

Expand Down Expand Up @@ -47,6 +47,21 @@ describe('translateWgslTypeToGlsl', () => {
});
});

describe('GlslGenerator', () => {
it('reports "glsl" as the language', () => {
function foo() {
'use gpu';
return std.getTargetShaderLanguage() === 'glsl';
}

expect(tgpu.resolve([foo], glOptions())).toMatchInlineSnapshot(`
"bool foo() {
return true;
}"
`);
});
});

describe('GlslGenerator - variable declarations', () => {
it('generates GLSL-style variable declarations for JS function', () => {
const main = () => {
Expand Down
12 changes: 7 additions & 5 deletions packages/typegpu/src/std/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,11 @@ impl[$gpuCallable] = {
export const isBeingTranspiled = impl;

/**
* Returns `wgsl` if invoked during the resolution process; otherwise, returns `undefined`.
* If invoked during the resolution process, it returns the name of the shader language that
* is ultimately being generated (usually `wgsl`); otherwise, returns `undefined`.
*
* @example
* const f = () => {
* function f() {
* 'use gpu';
* return getTargetShaderLanguage() === 'wgsl';
* };
Expand All @@ -48,14 +49,15 @@ export const isBeingTranspiled = impl;
* }
*
* @note
* Inside `lazy`, it always returns `wgsl`.
* Inside `simulate`, it always returns `undefined`.
* Inside `comptime`, it returns `wgsl` if called during the resolution process; otherwise, `undefined`.
*
* Inside `comptime`, it returns the shader language that is ultimately
* being generated (usually `wgsl`) if called during the resolution process; otherwise, `undefined`.
*/
export const getTargetShaderLanguage = comptime((() => {
const ctx = getResolutionCtx();
if (!ctx) {
return undefined;
}
return getExecMode().type !== 'simulate' ? 'wgsl' : undefined;
return getExecMode().type !== 'simulate' ? ctx.gen.languageKey : undefined;
}) as () => string | undefined);
2 changes: 2 additions & 0 deletions packages/typegpu/src/tgsl/shaderGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ export interface VariableDefinitionOptions {
* shader code in the target language (WGSL, GLSL, etc.).
*/
export interface ShaderGenerator {
readonly languageKey: string;

initGenerator(ctx: GenerationCtx): void;

declareGlobalConst(options: ConstantDefinitionOptions): ResolvedSnippet;
Expand Down
7 changes: 7 additions & 0 deletions packages/typegpu/src/tgsl/wgslGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,13 @@ export class WgslGenerator implements ShaderGenerator {
// used to detect `continue` and `break` nodes in loop body
#unrolling = false;

// prototype properties
declare languageKey: string;

static {
WgslGenerator.prototype.languageKey = 'wgsl';
}

public initGenerator(ctx: GenerationCtx) {
this.#ctx = ctx;
}
Expand Down
Loading