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.