Macro vulkanology::pipeline [] [src]

macro_rules! pipeline {
    {
        shader_path: $shader_path:expr,
        workgroup_count: $workgroup_count:expr,
        buffers: { $( $buf_ident:ident : [$buf_type:ty;$buf_len:expr] ),* },
        execution_command: $exec_cmd:ident
    } => { ... };
}

This macro is the core of the shader-testing framework. It generates code for initializing the vulkano environment, it allocates CpuAccessibleBuffers, it compiles the shader, it sets up a ComputePipeline and provides a function for executing the shader.

Panics

  • If the instance, physical_device, device or queue cannot be selected/initialized.
  • If the buffers cannot be initialized.
  • If the shader cannot be loaded.
  • If the pipeline cannot be created.

Example

// The total number of invocations of your shader is defined in two places:
//      - The workgroup_count, which is defined in the pipeline macro.
//      - The workgroup_size which is defined in the shader program header.

// Here we compute the total number of invocations. The workgroup size is `8x8x1`,
// and the workgroup count will be `100x100x1`.
let total_num_invocations = (8 * 8) * (100 * 100);

// I. Invoke the `pipeline!` macro.
// The macro parameters are:
//    1. The path to the shader program, relative to the crate root.
//        `shader_path: "path/to/shader/program.comp"`
//    2. A three-dimensional array defining the workgroup count:
//        `workgroup_count: [1, 2, 3],`
//    3. The buffers that your test shader uses:
//        `buffers: { input_data: [u32;4], some_buffer: [Dennis;42] },`
//    4. The name of the shader execution:
//        `execution_command: run_example_shader_function_name`
pipeline!{
    shader_path: "tests/shaders/example.comp",
    workgroup_count: [100, 100, 1],
    buffers: {
       data: [u32; total_num_invocations],
       result: [u32; total_num_invocations]
    },
    execution_command: execute_shader
}

// II. Fill your buffers with input data. The buffers are bound to the
//      names given in the `pipeline!` macro.
{
    use std::time::Duration;
    use rand::random;

    use vulkano::buffer::cpu_access::WriteLock;
    let mut mapping: WriteLock<[u32]> = data.write(Duration::new(1, 0)).unwrap();

    for item in mapping.iter_mut() {
        *item = random::<u32>();
    }
}

// III. Execute the shader.
//    `run_example_shader_function_name();`
execute_shader();

// IV. Assert validity of the results.
//    `assert!(datainbuffersisvalid())`
{
    use std::time::Duration;
    use vulkano::buffer::cpu_access::ReadLock;
    let input: ReadLock<[u32]> = data.read(Duration::new(1, 0)).unwrap();
    let output: ReadLock<[u32]> = result.read(Duration::new(1, 0)).unwrap();
    let zipped = input.iter().zip(output.iter());

    for (invocation_uid, (item_in, item_out)) in zipped.enumerate() {
        assert_eq!(*item_out, (*item_in).wrapping_mul(invocation_uid as u32));
    }
}