Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

naga-oil directive evaluation #38

Merged
merged 39 commits into from
May 20, 2024
Merged

naga-oil directive evaluation #38

merged 39 commits into from
May 20, 2024

Conversation

dannymcgee
Copy link
Owner

@dannymcgee dannymcgee commented May 12, 2024

This update significantly expands support for naga-oil modules.

The language server now accepts a preprocessor key, with this interface:

export interface Preprocessor {
  globalShaderDefs: Record<string, string>;
  shaderDefs: Record<string, Record<string, string>>;
}

An example configuration looks like this:

{
  "wgsl.preprocessor.globalShaderDefs": {
    "AVAILABLE_STORAGE_BUFFER_BINDINGS": "8",
    "PER_OBJECT_BUFFER_BATCH_SIZE": "64",
    "MAX_CASCADES_PER_LIGHT": "8",
    "MAX_DIRECTIONAL_LIGHTS": "4",
    "MORPH_TARGETS": "",
    "SKINNED": "",
    "VERTEX_POSITIONS": "",
    "SLICE_COUNT": "3",
    "SAMPLES_PER_SLICE_SIDE": "3"
  },
  "wgsl.preprocessor.shaderDefs": {
    "bevy_core_pipeline::tonemapping": {
      "TONEMAP_METHOD_AGX": ""
    }
  }
}

When WGSL documents are processed, conditional directives like the following are parsed and evaluated using the provided configuration:

#ifdef SKINNED
    // ...
#else
    // ...
#endif
#if AVAILABLE_STORAGE_BUFFER_BINDINGS >= 3
    // ...
#else
    // ...
#endif

Conditional branches that evaluate to false are marked inactive (with DiagnosticTag.Unnecessary) and removed from the input that's passed to the WGSL parser, along with all lines containing conditional directives.

Additionally, shader-def interpolations like the following are replaced with their configured values, with a helpful diagnostic if the server couldn't find a definition for the identifier:

#ifdef PER_OBJECT_BUFFER_BATCH_SIZE
// The WGSL parser will read this type as `array<Mesh, 64u>`
@group(1) @binding(0) var<uniform> mesh: array<Mesh, #{PER_OBJECT_BUFFER_BATCH_SIZE}u>;
#else
@group(1) @binding(0) var<storage> mesh: array<Mesh>;
#endif // PER_OBJECT_BUFFER_BATCH_SIZE
@compute
@workgroup_size(8, 8, 1)
fn gtao(@builtin(global_invocation_id) global_id: vec3<u32>) {
    // The parser will read this value as `f32(3)`
    let slice_count = f32(#SLICE_COUNT);
    // ...
}

Hovering over the #{PER_OBJECT_BUFFER_BATCH_SIZE} range in the editor displays a tooltip like the following, reflecting the value provided in the LSP configuration:

#define PER_OBJECT_BUFFER_BATCH_SIZE 64

Additionally, in-source #define statements like the example above are handled by the pre-parser in the same way.

Remaining Work

This update does not make any changes to the handling of module imports — while the server still provides features like hover tooltips, go-to-definition and reference lookups for imported/exported symbols, these elements are not yet expanded to valid WGSL source code before passing to the Naga validator, so Naga will still emit a parse error and exit early in any modules that include a #define_import_path or #import statement.

@dannymcgee dannymcgee mentioned this pull request May 12, 2024
@dannymcgee dannymcgee marked this pull request as ready for review May 20, 2024 18:13
@dannymcgee dannymcgee changed the title Preprocessing naga-oil directive evaluation May 20, 2024
@dannymcgee dannymcgee merged commit eeb31f0 into main May 20, 2024
1 check passed
@dannymcgee dannymcgee deleted the preprocessing2 branch May 20, 2024 21:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant