| #version 450 | |
| #extension GL_EXT_buffer_reference : require | |
| #extension GL_EXT_buffer_reference_uvec2 : require | |
| layout(local_size_x_id = 0) in; | |
| struct Command | |
| { | |
| uint type; | |
| uint src_offset; | |
| uint dst_offset; | |
| }; | |
| layout(buffer_reference, std430, buffer_reference_align = 4) readonly buffer Commands | |
| { | |
| Command commands[]; | |
| }; | |
| layout(buffer_reference, std430, buffer_reference_align = 4) readonly buffer SrcBuffer { | |
| uint values[]; | |
| }; | |
| layout(buffer_reference, std430, buffer_reference_align = 4) writeonly buffer DstBuffer { | |
| uint values[]; | |
| }; | |
| layout(buffer_reference, std430, buffer_reference_align = 4) readonly buffer IndirectCount { | |
| uint count; | |
| }; | |
| layout(buffer_reference, std430, buffer_reference_align = 4) writeonly buffer IndirectCountWrite { | |
| uint count; | |
| }; | |
| layout(push_constant) uniform Registers | |
| { | |
| Commands commands_va; | |
| SrcBuffer src_buffer_va; | |
| DstBuffer dst_buffer_va; | |
| uvec2 indirect_count_va; | |
| IndirectCountWrite dst_indirect_count_va; | |
| uint src_stride; | |
| uint dst_stride; | |
| }; | |
| void main() | |
| { | |
| Command cmd = commands_va.commands[gl_LocalInvocationIndex]; | |
| uint draw_id = gl_WorkGroupID.x; | |
| uint max_draws = gl_NumWorkGroups.x; | |
| if (any(notEqual(indirect_count_va, uvec2(0)))) | |
| { | |
| max_draws = min(max_draws, IndirectCount(indirect_count_va).count); | |
| if (gl_WorkGroupID.x == 0u) | |
| dst_indirect_count_va.count = max_draws; | |
| } | |
| if (draw_id < max_draws) | |
| { | |
| uint src_offset = src_stride * draw_id + cmd.src_offset; | |
| uint dst_offset = dst_stride * draw_id + cmd.dst_offset; | |
| uint src_value = src_buffer_va.values[src_offset]; | |
| dst_buffer_va.values[dst_offset] = src_value; | |
| } | |
| } |