fidget-wgpu 0.5.0

WGPU backend for Fidget
Documentation
const STACK_SIZE_WORDS: u32 = 32; // number of u32 words in the stack
const STACK_SIZE_BITS: u32 = STACK_SIZE_WORDS * 32u;
const STACK_SIZE_ITEMS: u32 = STACK_SIZE_WORDS * 16u;

const CHOICE_LEFT: u32 = 1;
const CHOICE_RIGHT: u32 = 2;
const CHOICE_BOTH: u32 = 3;

// Lossy stack, which expects a set of pushes followed by a set of pops
// (mixing pushes and pops is not allowed)
struct Stack {
    /// Current bitwise offset in the stack
    offset: u32,

    /// Number of items stored in the stack, (saturating at STACK_SIZE_ITEMS)
    valid_count: u32,

    /// Has a CHOICE_LEFT or CHOICE_RIGHT been pushed to the stack?
    has_choice: bool,

    /// Raw stack data
    data: array<u32, STACK_SIZE_WORDS>,
}

// Pushes a value to the stack, wrapping on overflow
fn stack_push(s: ptr<function, Stack>, v: u32) {
    let word_offset = s.offset % 32u;
    let word_index = s.offset / 32u;

    let mask = 3u << word_offset;
    s.data[word_index] &= ~mask;
    s.data[word_index] |= (v & 3u) << word_offset;

    s.has_choice |= (v == CHOICE_LEFT) || (v == CHOICE_RIGHT);

    s.offset = (s.offset + 2u) % STACK_SIZE_BITS;
    s.valid_count = min(s.valid_count + 1, STACK_SIZE_ITEMS);
}

// Pops a value from the stack, returning CHOICE_BOTH on underflow
fn stack_pop(s: ptr<function, Stack>) -> u32 {
    if s.valid_count == 0u {
        return CHOICE_BOTH;
    }
    s.valid_count -= 1;

    s.offset = (s.offset + STACK_SIZE_BITS - 2u) % STACK_SIZE_BITS;
    let word_offset = s.offset % 32u;
    let word_index = s.offset / 32u;

    return (s.data[word_index] >> word_offset) & 3u;
}