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.