Skip to content
Merged
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
168 changes: 115 additions & 53 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ keywords = ["gamedev", "graphics"]
categories = ["graphics"]

[dev-dependencies]
naga = { version = "23", features = ["spv-in", "wgsl-out"]}
naga = { version = "29", features = ["spv-in", "wgsl-out"]}
spirv-tools = "0.13"

51 changes: 50 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,24 @@ When porting native games to the web using WebGPU, it becomes neccessary to tran
Unfortunately, the WGSL specification lacks support for many features that have shader programmers have become accustomed to.
This project aims to transform common but unsupported SPIRV shaders into a form that `naga` and `tint` can transpile.

This also includes an interface for some dodging unsupported features or features that may not run on older browser versions.

## Feature Summary

At the moment, the following transformations are supported:

| Feature | `spirv-val` | `naga` | `tint` |
| --------------------------------- | ----------- | ------ | ------ |
| Combined Image Samplers | ✅ | ✅ | ✅ |
| Immediates (Push Constants) | ✅ | ✅\* | ✅ |
| Mixed Depth / Comparison | ✅ | ⚠️\* | ❌ |
| isnan / isinf Patching | ✅ | ✅ | ✅ |
| Storage Cube Patching | ✅ | ✅ | ✅ |
| Unused Image Sampler Pruning | ✅ | ✅ | ✅ |

> \* Simple cases are OK.
> (1)\* 99% OK, just one very specific padding related `naga` bug.

> (2)\* Simple cases are OK.
> With some [special patches](https://github.com/davnotdev/wgpu/tree/trunk-naga-patches), `naga` can process these.

## Combined Image Samplers
Expand Down Expand Up @@ -61,6 +66,50 @@ layout(set = 0, binding = 3) uniform sampler u_sampler;
| `test_arrayed.frag` | ✅ | ✅ | ✅ |
| `test_mixed.frag` | ✅ | ✅ | ✅ |

## Immediates (Push Constants)

Immediates, more commonly known as push constants came to the WebGPU spec late, so browser support is still unreliable (as of writing).
This patch replaces push constants with an equivalent uniform buffer.

```glsl
layout(std430, push_constant) uniform PushBlock {
vec4 color;
mat4 transform;
float scale;
...
} pc;

// is converted into...

layout(std140, set = N+1, binding = 0) uniform PushBlock {
vec4 color;
mat4 transform;
float scale;
...
} pc;

// where N is the max set in the shader.

```

### Additional Notes

- The converted uniform is placed in `set = N+1`, where `N` is the highest descriptor set already in use.
- Shaders that contain `mat2` (or any matrix with 2-row columns: `matCx2`) in the push constant block will not pass through `naga` specifically.
- To my knowledge, padding should not be a concern between uniforms, storage, and immediates.

### Tests

| Test | `spirv-val` | Naga | Tint |
| ----------------------- | ----------- | ------ | ---- |
| `immediates.frag` | ✅ | ✅ | ✅ |
| `mat2_direct.frag` | ✅ | ❌\* | ✅ |
| `array_of_mat2.frag` | ✅ | ✅ | ✅ |
| `nested_struct.frag` | ✅ | ✅ | ✅ |
| `row_major.frag` | ✅ | ✅ | ✅ |

> \* naga's SPIR-V front-end rejects `MatrixStride 16` for `mat2x2`, this should be fixed soon (?).

## Mixed Depth / Comparison

The WGSL spec differentiates between `sampler` and `sampler_comparison` as well as `texture2d<T>` and `texture_depth_2d`.
Expand Down
2 changes: 2 additions & 0 deletions ffi/spirv_webgpu_transform.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ void spirv_webgpu_transform_combimgsampsplitter_alloc(uint32_t *in_spv, uint32_t
void spirv_webgpu_transform_combimgsampsplitter_free(uint32_t *out_spv);
void spirv_webgpu_transform_drefsplitter_alloc(uint32_t *in_spv, uint32_t in_count, uint32_t **out_spv, uint32_t *out_count, TransformCorrectionMap *correction_map);
void spirv_webgpu_transform_drefsplitter_free(uint32_t *out_spv);
void spirv_webgpu_transform_immediatespatch_alloc(uint32_t *in_spv, uint32_t in_count, uint32_t **out_spv, uint32_t *out_count);
void spirv_webgpu_transform_immediatespatch_free(uint32_t *out_spv);
void spirv_webgpu_transform_isnanisinfpatch_alloc(uint32_t *in_spv, uint32_t in_count, uint32_t **out_spv, uint32_t *out_count);
void spirv_webgpu_transform_isnanisinfpatch_free(uint32_t *out_spv);
void spirv_webgpu_transform_storagecubepatch_alloc(uint32_t *in_spv, uint32_t in_count, uint32_t **out_spv, uint32_t *out_count, TransformCorrectionMap *correction_map);
Expand Down
Loading
Loading