#spir-v #graphics #sampler #combined #gamedev #wgpu #image

bin+lib spirv_combimgsampsplitter

SPIRV combined image sampler splitter for wgpu

1 unstable release

new 0.3.0 Nov 14, 2024
0.2.3 Nov 7, 2024
0.2.1 Oct 14, 2024
0.1.1 Oct 1, 2024
0.1.0 Sep 30, 2024

#306 in Graphics APIs

Download history 506/week @ 2024-09-30 36/week @ 2024-10-07 183/week @ 2024-10-14 4/week @ 2024-10-21 239/week @ 2024-11-04 130/week @ 2024-11-11

378 downloads per month

BSD-2-Clause

39KB
885 lines

SPIRV Combined Image Sampler Splitter

Version Badge Docs Badge License Badge Downloads Badge

It is commonly known that WebGpu does not support combined image samplers. This makes adding WebGpu support for existing OpenGL or Vulkan renderers impossible without workarounds. This is one such workaround. By reading and modifying SPIRV byte code, combined image samplers can be split into their respective texture and sampler. Special edge cases such as the use of combined image samplers in function parameters and nested functions are also handled.

layout(set = 0, binding = 0) uniform sampler2D u_texture;
layout(set = 0, binding = 1) uniform sampler2DArray u_texture_array;

// is converted into...

layout(set = 0, binding = 0) uniform texture2D u_texture;
layout(set = 0, binding = 1) uniform sampler u_sampler;

// *texture2DArray doesn't exist in glsl, but in wgsl, this would be texture_2d_array<f32>
layout(set = 0, binding = 2) uniform texture2DArray u_texture_array;
layout(set = 0, binding = 3) uniform sampler u_sampler;
spirv_combimgsampsplitter = "0.3"

Enjoy!

Notes on WGSL Translation

Naga

Test Status
test.frag
test_nested.frag
test_arrayed.frag
test_mixed.frag

Tint

Test Status
test.frag
test_nested.frag
test_arrayed.frag
test_mixed.frag

Notes

  • Translating sampler2D[N] and sampler2DArray[N] is NOT supported.
  • After being split, the SPIR-V will not translate back to GLSL "one-to-one", the translation back to GLSL using either naga or tint creates a combined image sampler!
  • Do NOT use older versions of this crate, they are buggy.

Library Usage

let spv_bytes: Vec<u8> = fs::read("in.spv").unwrap();

let spv: Vec<u32> = spirv_combimgsampsplitter::u8_slice_to_u32_vec(&spv_bytes);
let out_spv: Vec<u32> = spirv_combimgsampsplitter::combimgsampsplitter(&spv).unwrap();

let out_spv_bytes = spirv_combimgsampsplitter::u32_slice_to_u8_vec(&out_spv);
fs::write("out.spv", out_spv_bytes).unwrap();

CLI Usage

spirv_combimgsampsplitter in.spv out.spv
# or
cargo r -- in.spv out.spv

No runtime deps