Source browser

examples/shaders/evt3_summary.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// Summarize independent EVT3 blocks. Two 16-bit sensor words share each uint.
2#ifdef __cplusplus // Include the runtime only when compiling the CPU adapter.
3#include "shdr.h" // Share the portable resource and math declarations.
4#endif // Finish the C++ declaration include guard.
5layout(local_size_x = 64) in; // Assign one independent block or event to each invocation.
6layout(std430, binding = 0) readonly buffer Input { // Read the packed sensor stream.
7    uint packed_words[]; // Read two little-endian 16-bit sensor words from each uint.
8}; // Finish this shader storage resource declaration.
9layout(std430, binding = 1) writeonly buffer Summaries { // Exchange compact block summaries between decoder stages.
10    uvec4 summaries[]; // Store three state and event-count records per input block.
11}; // Finish this shader storage resource declaration.
12uniform uint word_count; // Receive the number of valid 16-bit input words.
13uniform uint block_size; // Receive the maximum input words handled by one block.
14
15void main() { // Summarize this block using local state changes and event counts.
16    uint b = gl_GlobalInvocationID.x; // Select the input block summarized by this invocation.
17    uint begin = b * block_size; // Locate the first 16-bit word of this block.
18    if (begin >= word_count) // Ignore invocations beyond the last input block.
19        return; // Stop dispatch padding at the input-word boundary.
20    uint end = min(begin + block_size, word_count); // Clamp the final block to the valid input word count.
21    // Flags mark state fields replaced by this block, X otherwise adds to its seed.
22    uint flags = 0u, y = 0u, x = 0u, p = 0u, hi = 0u, lo = 0u; // Track replaced state fields and the block's final pixel and time state.
23    uint first_hi = 0u, wraps = 0u, total = 0u, after_sync = 0u; // Track the first high-time word, internal wraps and both event counts.
24    for (uint i = begin; i < end; ++i) { // Interpret this block's words in their original stream order.
25        uint word = (packed_words[i / 2u] >> ((i % 2u) * 16u)) & 65535u; // Extract the selected 16-bit word from its packed uint.
26        uint type = word >> 12u, value = word & 4095u; // Separate the four-bit word type from its twelve-bit payload.
27        uint emitted = 0u; // Initialize this word's emitted-event count to zero.
28        if (type == 0u) { // Handle a Y-coordinate and camera-state word.
29            y = value; // Remember the final Y-coordinate and camera bit.
30            flags |= 1u; // Mark Y and camera state as replaced by this block.
31        } else if (type == 3u) { // Handle a vector base coordinate and polarity word.
32            x = value & 2047u; // Replace the vector base with the eleven-bit X coordinate.
33            p = value >> 11u; // Remember the vector polarity bit.
34            flags |= 2u; // Mark the new vector X and polarity as absolute state replacements.
35        } else if (type == 4u || type == 5u) { // Handle a twelve-bit or eight-bit vector event mask.
36            uint bits = type == 4u ? value : value & 255u; // Keep only the mask bits belonging to this vector word type.
37            emitted = uint(bitCount(bits)); // Count one event for every set mask bit.
38            x = (x + (type == 4u ? 12u : 8u)) & 2047u; // Advance the vector base by this mask's width with eleven-bit wrapping.
39        } else if (type == 2u || type == 10u) // Count an absolute pixel event or external trigger word.
40            emitted = 1u; // Count the single record represented by this word.
41        else if (type == 6u) { // Handle a low twelve-bit timestamp word.
42            lo = value; // Remember the final low timestamp bits.
43            flags |= 8u; // Mark the low timestamp state as replaced.
44        } else if (type == 8u) { // Handle high timestamp bits and synchronization.
45            if ((flags & 4u) == 0u) // Record the first high-time word for cross-block wrap detection.
46                first_hi = value; // Save the first high-time payload seen in this block.
47            else if (hi > value && hi - value >= 4085u) // Recognize a high-time wrap using the EVT3 tolerated rollover range.
48                ++wraps; // Count another 24-bit timestamp rollover inside this block.
49            hi = value; // Remember the most recent high timestamp bits.
50            lo = 0u; // Reset low timestamp bits whenever a high-time word arrives.
51            flags |= 12u; // Mark both high and low timestamp fields as replaced.
52        } // Finish this decoder or fitting branch.
53        total += emitted; // Count all event-bearing words in this block.
54        if ((flags & 4u) != 0u) // Use the locally synchronized count for an initially unsynchronized stream.
55            after_sync += emitted; // Count events appearing after this block's first high-time word.
56    } // Finish this decoder or fitting branch.
57    summaries[3u * b] = uvec4(y, x, p, hi); // Publish final pixel, vector-polarity and high-time fields.
58    summaries[3u * b + 1u] = uvec4(lo, wraps, first_hi, flags); // Publish final low time, internal wraps, first high time and replacement flags.
59    summaries[3u * b + 2u] = uvec4(total, after_sync, 0u, 0u); // Publish total and newly synchronized event counts.
60} // Finish this decoder or fitting branch.