#vulkan #ffi #graphics #gpu #rendering

nobs-vkpipes

shader compilation, vulkan pipeline composition and descriptor set updating as extension to nobs-vk

1 unstable release

0.1.0 Feb 24, 2019

#71 in #rendering


Used in 2 crates (via nobs-vulkanism-headless)

MIT license

1MB
16K SLoC

nobs-vkpipes

Compiles shaders from glsl and generates rust code from spv.

Features

  1. Builder patterns for compute and graphics pipeline generation
  2. Descriptor set definitions for easy accessible descriptor writes and updates
  3. Code generation macros to compile pipeline and descriptor definitions with spv shader code into a rust module. Enables one liner pipeline instantiation and descriptor set allocation.

Documentation

Find a complete documentation of this library at docs.rs.

Setup

Follow the setup instructions for shaderc-rs.

After this you are ready to use nobs-vkpipes!

Contributing

Feel encouraged to contribute!


lib.rs:

nobs-vkpipes

Compiles shaders from glsl and generates rust code from spv.

This crate provides builder pattern implementations for vulkan pipeline creation and descriptor set updating.

Example

This is a simple example that sets up a compute pipeline.

All the magic happens in vk::pipes::pipeline! macro! We define the pipeline with several comma separated fields, paths are always specified relative to the compilied crate's cargo.toml:

See the reexported macros pipeline and shader for a list of configurable options.

extern crate nobs_vulkanism as vk;
// IMPORTANT import these two crates with their original name
// (e.g. not extern crate nobs_vk as vk)
// Otherwise the code generation will genertate code
// that does not find symbols defined there
// You can still use this...

// declare the module that will contain our pipeline
mod make_sequence {
  vk::pipes::pipeline!{
    dset_name[0] = "Dset",
    stage = {
      ty = "comp",
      glsl = "
#version 450
#extension GL_ARB_separate_shader_objects : enable

const uint GROUP_SIZE = 512;

layout(binding = 0) uniform ub {
  uint num_elems;
  uint i_first;
  uint i_step;
};

layout(binding = 1) buffer b_out {
  uint bout[];
};

layout(local_size_x = GROUP_SIZE) in;
void main() {
  // copy input values for group in shared memory
  uint gid = gl_GlobalInvocationID.x;

  if (gid < num_elems) {
    bout[gid] = i_first + gid * i_step;
  }
}
        ",
    }
  }

  // The code generation will not create types for e.g. the uniform buffer
  // If we want this, we need to do it our selves
  pub struct ub {
    pub num_elems: u32,
    pub i_first: u32,
    pub i_step: u32,
  }
}

// create an instance of the pipeline
// uses the nobs_vk::DeviceExtensions to build the pipeline
let p = make_sequence::build(device.handle).new().unwrap();

// update the descriptor set
make_sequence::dset::write(device.handle, ds)
  .ub(|b| b.buffer(buf_ub))
  .b_out(|b| b.buffer(buf_out))
  .update();

Dependencies