Source browser

examples/shaders/rle_encode.cpp

Read the complete file below or download its original bytes. Line numbers provide stable links to a declaration or processing step.

File fingerprint
1// Lossless tiled RLE: disjoint tile ranges produce one compact global word stream.
2#ifdef __cplusplus // Expose host declarations only when a C++ compiler reads this shader.
3#include "shdr.h" // Include shdr.h declarations.
4#endif // Finish this conditional compilation branch.
5layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in; // Group 64 independent invocations along x.
6layout(std430, binding = 0) readonly buffer Values { // Read the original unsigned values to encode through buffer binding 0.
7    uint values[]; // Store the original unsigned values to encode.
8}; // Finish this declaration.
9layout(std430, binding = 1) readonly buffer Offsets { // Read exclusive tile offsets followed by the complete payload size through buffer binding 1.
10    uint offsets[]; // Store exclusive tile offsets followed by the complete payload size.
11}; // Finish this declaration.
12layout(std430, binding = 2) writeonly buffer Encoded { // Write alternating original values and unsigned run lengths through buffer binding 2.
13    uint encoded[]; // Store alternating original values and unsigned run lengths.
14}; // Finish this declaration.
15uniform uint count; // Limit work to the valid element count, including a partial final workgroup.
16uniform uint block_size; // Limit each independent encoder or decoder to this many original values.
17void main() { // Write the lossless value and run-length pairs for one tile.
18    uint block = gl_GlobalInvocationID.x; // Assign one independent input tile to this invocation.
19    uint begin = block * block_size; // Locate the first original value in this tile.
20    if (begin >= count) // Ignore workgroup padding after the final tile.
21        return; // Stop this invocation before performing another resource access.
22    uint end = min(begin + block_size, count); // Stop the last tile at the actual input length.
23    uint write_position = offsets[block]; // Use the prefix stage's disjoint destination range for this tile.
24    uint value = values[begin]; // Begin the first run with the tile's first original value.
25    uint run = 1u; // Count the first sample in the current run.
26    for (uint i = begin + 1u; i < end; ++i) { // Scan the remaining original values in this tile.
27        if (values[i] == value) // Extend the current run when its value repeats.
28            ++run; // Include this repeated value in the current run.
29        else { // Emit the completed run and start a run for the newly encountered value.
30            encoded[write_position++] = value; // Write the original value of the completed run.
31            encoded[write_position++] = run; // Write the number of repetitions and advance to the next pair.
32            value = values[i]; // Start the next run with this newly encountered value.
33            run = 1u; // Count the first sample in the new run.
34        } // End this block.
35    } // End this block.
36    encoded[write_position++] = value; // Write the original value of the completed run.
37    encoded[write_position] = run; // Finish the final run in this tile with its repetition count.
38} // End this block.