Vireo  0.0
Vireo 3D Rendering Hardware Interface
Compute Pipelines

A compute pipeline is a GPU pipeline specialized for running general-purpose compute shaders (rather than the fixed‐function stages of graphics pipelines). It as a single programmable stage : the compute shader.

Because it omits all the fixed‐function graphics stages, the compute pipeline gives you maximum flexibility and performance for purely computational tasks on the GPU, executed in parallel.

Use cases of compute shaders :

  • Physics simulations
  • Particle systems
  • Image processing / post-processing
  • Special effects
  • Advanced lighting calculations
  • General data-parallel algorithms

For more information about compute pipelines and dispatching work read Compute with DirectX 12 by Stefan Pijnacker

Creating a compute pipeline

A Compute pipeline is created with vireo::Vireo::createComputePipeline. Unlike graphic pipelines there is not configuration object since the is nothing to configure. Only the pipeline resources and the shader module are needed :

pipeline = vireo->createComputePipeline(
vireo->createPipelineResources( { descriptorLayout }),
vireo->createShaderModule("shaders/compute.comp"));

Dispatching work

To execute the shader, bind the compute pipeline with vireo::CommandList::bindPipeline and its descriptor sets with vireo::CommandList::bindDescriptors, then issue a dispatch call with vireo::CommandList::dispatch specifying a 3D grid of workgroups.

Each workgroup invokes the compute shader on one or more GPU threads (they are very light threads compared to CPU threads).

// Set the descriptor sets list
frame.commandList->setDescriptors({frame.descriptorSet});
// Update the destination image in the descriptor set
frame.descriptorSet->update(BINDING_IMAGE, frame.image);
// Bind the compute pipeline
frame.commandList->bindPipeline(pipeline);
// Bind the descriptor sets
frame.commandList->bindDescriptors(pipeline, {frame.descriptorSet});
// Prepare the destination image
frame.commandList->barrier(
frame.image,
// Dispatch work on the GPU
frame.commandList->dispatch((frame.image->getWidth() + 7)/8, (frame.image->getHeight() + 7)/8, 1);
...
Note
The destination image must be a vireo::DescriptorType::READWRITE_IMAGE created with vireo::Vireo::createReadWriteImage. If you need to do non-graphic computational work just consider the image as an array...