[][src]Module web_glitz::task

Provides a framework for specifying units of work that are to be executed by the GPU driver.

WebGlitz's execution model centers around the concepts of "tasks" and "commands". A "task" is a unit of work that is to be executed on a graphical processing unit (GPU). A "command" is an atomic task; a task may composed of multiple commands. There is not a specific type that represents a command in this library, both tasks and commands are represented by the GpuTask trait. The term "command" is only used by convention for the atomic task building blocks provided by WebGlitz that you may combine into more complex tasks.

The following example shows how we may create a task consists of a single command that uploads image data to the base level of a Texture2D:

use web_glitz::image::{Image2DSource, MipmapLevels};
use web_glitz::image::format::RGB8;
use web_glitz::image::texture_2d::Texture2DDescriptor;

// First we create the texture that we are going to upload to:
let texture = context.try_create_texture_2d(&Texture2DDescriptor {
    format: RGB8,
    width: 256,
    height: 256,
    levels: MipmapLevels::Complete
}).unwrap();

// Next, we define some data we wish to upload
let pixels: Vec<[u8; 3]> = vec![[255, 0, 0]; 256 * 256];
let data = Image2DSource::from_pixels(pixels, 256, 256).unwrap();

// Finally, we define a task that consist of a single upload command that will upload our data:
let task = texture.base_level().upload_command(data);

Here context is a RenderingContext. For more information on textures, please refer to the documentation for the [image] module.

Task combinators

Combining tasks and commands into more complex tasks is done by "sequencing" or "joining". Both sequencing and joining involve combining 2 or more sub-tasks into 1 new combined task, but they have different guarantees about the order in which these sub-tasks are executed.

A sequence may be created with functions such as [sequence], sequence3, sequence4, sequence5 or sequence_iter, or the with [sequence_all] macro, which sequences any number of sub-tasks. In all cases, the sub-tasks are considered to have an order that corresponds to the order in which they were passed to these functions/the macro. A sub-task in a sequence only begins executing after the previous sub-task in this ordering has finished executing completely. The sequence is considered to be finished when the last sub-task has finished executing. The following example expands on the previous example by adding a command that generates mipmap data for the texture:

use web_glitz::image::{Image2DSource, MipmapLevels};
use web_glitz::image::format::RGB8;
use web_glitz::image::texture_2d::Texture2DDescriptor;
use web_glitz::task::sequence;

let texture = context.try_create_texture_2d(&Texture2DDescriptor {
    format: RGB8,
    width: 256,
    height: 256,
    levels: MipmapLevels::Complete
}).unwrap();

let pixels: Vec<[u8; 3]> = vec![[255, 0, 0]; 256 * 256];
let data = Image2DSource::from_pixels(pixels, 256, 256).unwrap();

// This time our tasks consists of a sequence of two commands:
let task = sequence(
    texture.base_level().upload_command(data),
    texture.generate_mipmap_command()
);

This example will first upload our data to the texture's base level. Then, after the data has finished uploading, the data for the remaining texture levels is generated with a "generate mipmap" command. For details on mipmapping and mipmap levels, see the documentation for the [image] module.

A join may be created with functions such as [join], join3, join4, join5 or join_iter, or the with [join_all] macro, which joins any number of sub-tasks. Joining is similar to sequencing, except for that joining does not give any guarantees about the order in which the sub-tasks begin executing. The join is considered to have finished when all sub-tasks have finished executing. A join may be faster than a sequence.

The following example shows how we might upload data to the base level for all faces of a TextureCube, before generating the data for the remaining levels with a "generate mipmap" command:

use web_glitz::image::{Image2DSource, MipmapLevels};
use web_glitz::image::format::RGB8;
use web_glitz::image::texture_cube::TextureCubeDescriptor;
use web_glitz::task::{join_all, sequence_all};

// First we create the cube-map texture we are going to upload to:
let texture = context.try_create_texture_cube(&TextureCubeDescriptor {
    format: RGB8,
    width: 256,
    height: 256,
    levels: MipmapLevels::Complete
}).unwrap();

// Then we define some data for each of the cube-map faces:
let positive_x_pixels: Vec<[u8; 3]> = vec![[255, 0, 0]; 256 * 256];
let positive_x_data = Image2DSource::from_pixels(positive_x_pixels, 256, 256).unwrap();
let negative_x_pixels: Vec<[u8; 3]> = vec![[0, 255, 0]; 256 * 256];
let negative_x_data = Image2DSource::from_pixels(negative_x_pixels, 256, 256).unwrap();
let positive_y_pixels: Vec<[u8; 3]> = vec![[0, 0, 255]; 256 * 256];
let positive_y_data = Image2DSource::from_pixels(positive_y_pixels, 256, 256).unwrap();
let negative_y_pixels: Vec<[u8; 3]> = vec![[255, 255, 0]; 256 * 256];
let negative_y_data = Image2DSource::from_pixels(negative_y_pixels, 256, 256).unwrap();
let positive_z_pixels: Vec<[u8; 3]> = vec![[255, 0, 255]; 256 * 256];
let positive_z_data = Image2DSource::from_pixels(positive_z_pixels, 256, 256).unwrap();
let negative_z_pixels: Vec<[u8; 3]> = vec![[0, 255, 255]; 256 * 256];
let negative_z_data = Image2DSource::from_pixels(negative_z_pixels, 256, 256).unwrap();

// Finally, we define our task:
let task = sequence_all![
    join_all![
        texture.base_level().positive_x().upload_command(positive_x_data),
        texture.base_level().negative_x().upload_command(negative_x_data),
        texture.base_level().positive_y().upload_command(positive_y_data),
        texture.base_level().negative_y().upload_command(negative_y_data),
        texture.base_level().positive_z().upload_command(positive_z_data),
        texture.base_level().negative_z().upload_command(negative_z_data),
    ],
    texture.generate_mipmap_command()
];

In this case, we don't really care about the order in which the uploads to each of the cube's faces finish, so we use the [join_all] macro to join them into a task. However, it is important that we do not begin generating the mipmap data for the remaining levels before all uploads have finished. We therefor use [sequence] to sequence our combined upload command with the "generate mipmap" command.

Note that all sequence and join functions and macros mentioned above also come in "left" and "right" variants. For example, sequence5 is accompanied by sequence5_left and sequence5_right. The difference is in the combined task's output (the future result of the task when it is submitted with [RenderingContext::submit], see below). sequence5 outputs a tuple of all 5 of the outputs of the 5 tasks it sequences. However, one is often only interested in just the output of either the left-most (the first) or right-most (the last) task in the sequence. This is where sequence5_left and sequence5_right come in: sequence5_left only outputs the output of the left-most task and sequence5_right only outputs the output of the right-most task. In all other aspects the behaviour of a task created with sequence5_left or sequence5_right is identical to the behaviour of a task created with sequence5.

Submitting tasks

A task merely describes work for the GPU, it does not actually do anything until it is submitted to a RenderingContext with [RenderingContext::submit]:

let future = context.submit(task);

This will return a Future that will resolve with the task's output (see GpuTask::Output) after the task has finished executing.

Re-exports

pub use crate::join_all;
pub use crate::join_all_left;
pub use crate::join_all_right;
pub use crate::sequence_all;
pub use crate::sequence_all_left;
pub use crate::sequence_all_right;

Structs

Empty
Join

Task for the join combinator, waiting for two tasks to complete in no particular order.

Join3

Task for the join3 combinator, waiting for three tasks to complete in no particular order.

Join3Left

Task for the join3_left combinator, waiting for three tasks to complete in no particular order and only outputting the output of the left-most task.

Join3Right

Task for the join3_right combinator, waiting for three tasks to complete in no particular order and only outputting the output of the right-most task.

Join4

Task for the join4 combinator, waiting for four tasks to complete in no particular order.

Join4Left

Task for the join4_left combinator, waiting for four tasks to complete in no particular order and only outputting the output of the left-most task.

Join4Right

Task for the join4_right combinator, waiting for four tasks to complete in no particular order and only outputting the output of the right-most task.

Join5

Task for the join5 combinator, waiting for five tasks to complete in no particular order.

Join5Left

Task for the join5_left combinator, waiting for five tasks to complete in no particular order and only outputting the output of the left-most task.

Join5Right

Task for the join5_right combinator, waiting for five tasks to complete in no particular order and only outputting the output of the right-most task.

JoinIter

Task for the join_iter combinator, waiting for all tasks in the iterator to complete in no particular order, outputting ().

JoinLeft

Task for the join_left combinator, waiting for two tasks to complete in no particular order and only outputting the output of the left-most task.

JoinRight

Task for the join_right combinator, waiting for two tasks to complete in no particular order and only outputting the output of the right-most task.

Map
OptionTask
Sequence

Task for the sequence combinator, waiting for two tasks to complete in order.

Sequence3

Task for the sequence3 combinator, waiting for three tasks to complete in order.

Sequence3Left

Task for the sequence3_left combinator, waiting for three tasks to complete order and only outputting the output of the left-most task.

Sequence3Right

Task for the sequence3_right combinator, waiting for three tasks to complete in order and only outputting the output of the right-most task.

Sequence4

Task for the sequence4 combinator, waiting for four tasks to complete in order.

Sequence4Left

Task for the sequence4_left combinator, waiting for four tasks to complete in order and only outputting the output of the left-most task.

Sequence4Right

Task for the sequence4_right combinator, waiting for four tasks to complete in order and only outputting the output of the right-most task.

Sequence5

Task for the sequence5 combinator, waiting for five tasks to complete in order.

Sequence5Left

Task for the sequence5_left combinator, waiting for five tasks to complete in order and only outputting the output of the left-most task.

Sequence5Right

Task for the sequence5_right combinator, waiting for five tasks to complete in order and only outputting the output of the right-most task.

SequenceIter

Task for the sequence_iter combinator, waiting for all tasks in the iterator to complete in no particular order, outputting ().

SequenceLeft

Task for the sequence_left combinator, waiting for two tasks to complete in order and only outputting the output of the left-most task.

SequenceRight

Task for the sequence_right combinator, waiting for two tasks to complete in order and only outputting the output of the right-most task.

Enums

ContextId

Returned from GpuTask::context_id, identifies the context(s) a GpuTask may be used with.

Progress

Returned from GpuTask::progress, signifies the current state of progress for the task.

Traits

GpuTask

Trait for types that represent a computational task is to be partly or completely executed on a GPU.

GpuTaskExt

Functions

join

Combines task a with another task b, waiting for both tasks to complete in no particular order.

join3

Combines task a, b and c, waiting for all tasks to complete in no particular order.

join3_left

Combines task a, b and c, waiting for all tasks to complete in no particular order, with the output of task a.

join3_right

Combines task a, b and c, waiting for all tasks to complete in no particular order, with the output of task c.

join4

Combines task a, b, c and d, waiting for all tasks to complete in no particular order.

join4_left

Combines task a, b, c and d, waiting for all tasks to complete in no particular order, with the output of task a.

join4_right

Combines task a, b, c and d, waiting for all tasks to complete in no particular order, with the output of task d.

join5

Combines task a, b, c, d and e, waiting for all tasks to complete in no particular order.

join5_left

Combines task a, b, c, d and e, waiting for all tasks to complete in no particular order, with the output of task a.

join5_right

Combines task a, b, c, d and e, waiting for all tasks to complete in no particular order, with the output of task e.

join_iter

Combines all tasks in an iterator, waiting for all tasks to complete in no particular order.

join_left

Combines task a with another task b, waiting for both tasks to complete in no particular order, with the output of task a.

join_right

Combines task a with another task b, waiting for both tasks to complete in no particular order, with the output of task a.

sequence

Combines task a with another task b, waiting for both tasks to complete in order.

sequence3

Combines task a, b and c, waiting for all tasks to complete in order.

sequence3_left

Combines task a, b and c, waiting for all tasks to complete in order, with the output of task a.

sequence3_right

Combines task a, b and c, waiting for all tasks to complete in order, with the output of task c.

sequence4

Combines task a, b, c and d, waiting for all tasks to complete in order.

sequence4_left

Combines task a, b, c and d, waiting for all tasks to complete in order, with the output of task a.

sequence4_right

Combines task a, b, c and d, waiting for all tasks to complete in order, with the output of task d.

sequence5

Combines task a, b, c, d and e, waiting for all tasks to complete in order.

sequence5_left

Combines task a, b, c, d and e, waiting for all tasks to complete in order, with the output of task a.

sequence5_right

Combines task a, b, c, d and e, waiting for all tasks to complete in order, with the output of task e.

sequence_iter

Combines all tasks in an iterator, waiting for all tasks to complete in order.

sequence_left

Combines task a with another task b, waiting for both tasks to complete in order, with the output of task a.

sequence_right

Combines task a with another task b, waiting for both tasks to complete in order, with the output of task a.