ConvertIndirectDataShaderSource.comp
1 #version 450 core 2 3 #extension GL_EXT_scalar_block_layout : require 4 5 layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in; 6 7 layout (std430, set = 0, binding = 0) uniform draw_count_uniform 8 { 9 uint[64] draw_count_buffer; 10 }; 11 12 layout (std430, set = 1, binding = 1) buffer indirect_in 13 { 14 int[] indirect_data_in; 15 }; 16 17 layout (std430, set = 1, binding = 2) buffer indirect_out 18 { 19 int[] indirect_data_out; 20 }; 21 22 layout (std430, set = 1, binding = 3) buffer index_buffer_pattern 23 { 24 int ibp_pattern[8]; 25 int ibp_primitive_vertices; 26 int ibp_primitive_vertices_out; 27 int ibp_index_size; 28 int ibp_index_size_out; 29 int ibp_base_index; 30 int ibp_index_stride; 31 int src_offset; 32 int total_primitives; 33 int dispatch_x; 34 int dispatch_y; 35 int dispatch_z; 36 int has_draw_count; 37 uint max_draw_count; 38 int draw_count_offset; 39 int indirect_data_stride; 40 int indirect_data_offset; 41 }; 42 43 int GetPrimitiveCount(int vertexCount) 44 { 45 return max(0, (vertexCount - ibp_base_index) / ibp_index_stride); 46 } 47 48 int GetConvertedCount(int indexCount) 49 { 50 int primitiveCount = GetPrimitiveCount(indexCount); 51 return primitiveCount * ibp_primitive_vertices_out; 52 } 53 54 void main() 55 { 56 uint drawCount = has_draw_count != 0 ? min(draw_count_buffer[draw_count_offset], max_draw_count) : max_draw_count; 57 uint i = 0; 58 59 if (drawCount != 0) 60 { 61 int firstIndex = indirect_data_in[indirect_data_offset + 2]; 62 int endIndex = firstIndex + indirect_data_in[indirect_data_offset]; 63 64 for (i = 1; i < drawCount; i++) 65 { 66 int offset = int(i) * indirect_data_stride; 67 int inOffset = indirect_data_offset + offset; 68 69 int currentFirstIndex = indirect_data_in[inOffset + 2]; 70 firstIndex = min(firstIndex, currentFirstIndex); 71 endIndex = max(endIndex, currentFirstIndex + indirect_data_in[inOffset]); 72 } 73 74 int indexCount = endIndex - firstIndex; 75 76 dispatch_x = (indexCount + 15) / 16; 77 src_offset += firstIndex * ibp_index_size; 78 total_primitives = GetPrimitiveCount(indexCount); 79 80 for (i = 0; i < drawCount; i++) 81 { 82 int offset = int(i) * indirect_data_stride; 83 int inOffset = indirect_data_offset + offset; 84 85 indirect_data_out[offset] = GetConvertedCount(indirect_data_in[inOffset]); // Index count 86 indirect_data_out[offset + 1] = indirect_data_in[inOffset + 1]; // Instance count 87 indirect_data_out[offset + 2] = GetConvertedCount(indirect_data_in[inOffset + 2] - firstIndex); // First index 88 indirect_data_out[offset + 3] = indirect_data_in[inOffset + 3]; // Vertex offset 89 indirect_data_out[offset + 4] = indirect_data_in[inOffset + 4]; // First instance 90 } 91 } 92 93 for (; i < max_draw_count; i++) 94 { 95 int offset = int(i) * indirect_data_stride; 96 97 indirect_data_out[offset] = 0; 98 indirect_data_out[offset + 1] = 0; 99 indirect_data_out[offset + 2] = 0; 100 indirect_data_out[offset + 3] = 0; 101 indirect_data_out[offset + 4] = 0; 102 } 103 }