vkd3d-proton/libs/vkd3d/shaders/cs_resolve_query.comp

62 lines
1.5 KiB
Plaintext

#version 450
#extension GL_ARB_gpu_shader_int64 : require
layout(local_size_x = 64) in;
layout(constant_id = 0) const uint c_field_count = 1;
layout(std430, binding = 0)
buffer dst_queries_t {
uint64_t dst_queries[];
};
layout(std430, binding = 1)
readonly buffer src_queries_t {
uint64_t src_queries[];
};
struct query_map_entry_t {
uint dst_index;
uint src_index;
uint next;
};
layout(std430, binding = 2)
readonly buffer query_map_t {
query_map_entry_t entries[];
} map;
layout(push_constant)
uniform u_info_t {
uint query_count;
uint entry_offset;
};
void main() {
uint thread_id = gl_GlobalInvocationID.x;
if (thread_id >= query_count)
return;
// The query map is an array of linked lists, with the
// first query_count entries guaranteed to be list heads
query_map_entry_t entry = map.entries[thread_id + entry_offset];
uint64_t dst_data[c_field_count];
// By copying the first query we get the reset for free
for (uint i = 0; i < c_field_count; i++)
dst_data[i] = src_queries[c_field_count * entry.src_index + i];
// Accumulate data from additional queries
while (entry.next != ~0u) {
entry = map.entries[entry.next + entry_offset];
for (uint i = 0; i < c_field_count; i++)
dst_data[i] += src_queries[c_field_count * entry.src_index + i];
}
// dst_index has the same value for all entries in the list
for (uint i = 0; i < c_field_count; i++)
dst_queries[c_field_count * entry.dst_index + i] = dst_data[i];
}