in WebGpu, what is the stride and size of a Boolean?

104 views Asked by At

In the memory layout section in the WebGPU shading language, alignment and size are specified for many primitive types, vectors, arrays and matrices, but nothing is mentioned for bool.

also in the type definitions, int/float types are detailed about what memory they use and how, while for bool, the spec only mentions it has 2 values: true and false

How should the bool type actually be implemented (bitwise), and what stride and size does it have in structs?

2

There are 2 answers

0
gman On BEST ANSWER

in WGSL, at least version 1, there is no bool type that you can pass into/out of a shader so in general so there is no "memory layout" for a bool. You only need to know the size for computing things like workgroup storage size limits, not for memory layout

You can see this if you try to use them:

async function main() {
  const adapter = await navigator.gpu?.requestAdapter();
  const device = await adapter?.requestDevice();
  if (!device) {
    fail('need a browser that supports WebGPU');
    return;
  }

  const codes = [
    `
      @group(0) @binding(0) var<uniform> b: bool;
    `,
    `
      @group(0) @binding(0) var<storage> b: bool;
    `,
    `
      struct Uni {
        b: bool,
      };
      @group(0) @binding(0) var<uniform> u: Uni;
    `,
    `
      struct Uni {
        b: bool,
      };
      @group(0) @binding(0) var<storage> u: Uni;
    `,
  ];

  for (const code of codes) {
    const module = device.createShaderModule({code});
    const info = await module.getCompilationInfo();
    log('=========');
    log(code);
    log('-----');
    for (const msg of info.messages) {
      log(msg.message);
    }
  }
}

function log(...args) {
  const elem = document.createElement('pre');
  elem.textContent = args.join(' ');
  document.body.appendChild(elem);
}

main();
pre { margin: 0; }

In Chrome v120 the code above produces these error messages

=========

      @group(0) @binding(0) var<uniform> b: bool;
    
-----
Type 'bool' cannot be used in address space 'uniform' as it is non-host-shareable
while instantiating 'var' b
=========

      @group(0) @binding(0) var<storage> b: bool;
    
-----
Type 'bool' cannot be used in address space 'storage' as it is non-host-shareable
while instantiating 'var' b
=========

      struct Uni {
        b: bool,
      };
      @group(0) @binding(0) var<uniform> u: Uni;
    
-----
Type 'bool' cannot be used in address space 'uniform' as it is non-host-shareable
while analyzing structure member Uni.b
while instantiating 'var' u
=========

      struct Uni {
        b: bool,
      };
      @group(0) @binding(0) var<storage> u: Uni;
    
-----
Type 'bool' cannot be used in address space 'storage' as it is non-host-shareable
while analyzing structure member Uni.b
while instantiating 'var' u

If you want to pass bool values into your shader you'll have to pass them in via some other format and convert them in the shader. For example, you could pass 32 bits as a u32 and convert each bit to a bool in the shader.

@group(0) @binding(0) var<uniform> thirtyTwoBools: u32;
...
let b0 = bool(thirtyTwoBools & 0x01);
let b1 = bool(thirtyTwoBools & 0x02);
...

Or you could pass one u32 per bool and convert in the shader.

@group(0) @binding(0) var<uniform> oneBool: u32;
...
let b0 = bool(oneBool);

Or pass four bool as bytes per u32

@group(0) @binding(0) var<uniform> fourBoolsAsBytes: u32;
...
let b0 = bool(fourBoolsAsBytes & 0xFF);
let b1 = bool(fourBoolsAsBytes & 0xFF00);
let b2 = bool(fourBoolsAsBytes & 0xFF0000);
...

etc...

1
Samathingamajig On

From a table on that page, it seems like a bool is 1 byte

enter image description here

https://www.w3.org/TR/WGSL/#limits

I went through every ctrl/cmd+f search of "bool" and these are the only two references I see to bools that mention a size in bytes