OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-tps / distribute / hypertps-win64 / shaders / prepare_dispatch.glsl

46 lines · glsl ref:
#version 450

// ============================================================================
// Prepare indirect dispatch args + active element count from prefix sum.
//
// Reads the last element of the prefix sum and the last flag to compute
// the total number of active elements:
//     total = scan[N-1] + flags[N-1]
//
// Writes:
//   out_count[count_idx] = total
//   dispatch_args[out_offset + 0..2] = { ceil(active/256), 1, 1 }
//
// This eliminates a GPU->CPU->GPU roundtrip that was previously needed
// to read the active count between scan and intersect/solve stages.
//
// Dispatch: (1, 1, 1)  — single invocation
// ============================================================================

layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;

layout(set = 0, binding = 0, std430) readonly  buffer ScanBuf      { uint scan_data[];     };
layout(set = 0, binding = 1, std430) readonly  buffer FlagsBuf     { uint flags_data[];    };
layout(set = 0, binding = 2, std430) writeonly buffer DispatchArgs  { uint dispatch_args[]; };
layout(set = 0, binding = 3, std430)           buffer CountsBuf    { uint out_count[];     };

layout(push_constant) uniform PrepareDispatchPC {
    uint N;          // total elements in scan/flags arrays
    uint out_offset; // offset into dispatch_args (in uints): 0 for edges, 3 for voxels
    uint count_idx;  // index into out_count[]: 0 for edge_count, 2 for voxel_count
    uint _pad;
};

void main() {
    uint total_active = scan_data[N - 1u] + flags_data[N - 1u];

    out_count[count_idx] = total_active;

    uint groups = (total_active + 255u) / 256u;
    if (groups == 0u) groups = 1u;  // at least 1 group to avoid zero-dispatch

    dispatch_args[out_offset + 0u] = groups;
    dispatch_args[out_offset + 1u] = 1u;
    dispatch_args[out_offset + 2u] = 1u;
}