gKit2 light
Loading...
Searching...
No Matches
count_buffer.glsl
Go to the documentation of this file.
1
3
4#version 430
5
6#extension GL_KHR_shader_subgroup_basic : require
7#extension GL_KHR_shader_subgroup_arithmetic : require
8#extension GL_KHR_shader_subgroup_ballot : require
9
10#ifdef COMPUTE_SHADER
11
12layout( std430, binding= 0 ) buffer inputData
13{
14 int a[];
15};
16
17layout( std430, binding= 1 ) buffer outputData
18{
19 int b[];
20};
21
22layout( std430, binding= 2 ) buffer countData
23{
24 uint count;
25};
26
27uniform int v= 5;
28
29shared uint group_count;
30shared uint group_offset;
31
32layout( local_size_x=256 ) in;
33void main( )
34{
35 uint ID= gl_GlobalInvocationID.x;
36
37/* version directe...
38 if(a[ID] < v)
39 {
40 uint index= atomicAdd(count, 1);
41 b[index]= a[ID];
42 }
43*/
44
45/* version decomposee par groupe
46 // 0. init
47 if(gl_LocalInvocationIndex == 0)
48 group_count= 0;
49 barrier();
50
51 // 1. evaluer la condition / predicat
52 uint offset= -1;
53 if(a[ID] < v)
54 offset= atomicAdd(group_count, 1);
55
56 // group_count contient le nombre de threads qui veulent ecrire un resultat dans le buffer
57 // et offset contient la position du resultat dans le groupe...
58
59 // 2. reserver une place pour les resultats du groupe dans le buffer
60 if(gl_LocalInvocationIndex == 0)
61 group_offset= atomicAdd(count, group_count);
62 barrier();
63 // group_offset contient la position des resultats du groupe dans le buffer resultat
64
65 // 3. ecrire les resultats
66 if(offset != -1)
67 // ecrit la valeur lorsqu'elle verifie la condition et qu'elle a une position...
68 b[group_offset+offset]= a[ID];
69 // toutes les valeurs d'un groupe sont ecrites en sequence dans le buffer resultat
70 */
71
72/* version shader_subgroup, decomposée par sous groupe
73 */
74 // 0. init
75 if(gl_LocalInvocationIndex == 0) // 1 seule fois par groupe !
76 group_count= 0;
77 barrier();
78
79 // 1. evaluer la condition / predicat
80 uvec4 mask= subgroupBallot( (a[ID] < v) );
81
82 uint subgroup_count= subgroupBallotBitCount(mask);
83 uint subgroup_offset= subgroupBallotExclusiveBitCount(mask);
84
85 uint offset;
86 if(gl_SubgroupInvocationID == 0) // 1 thread par sous groupe
87 offset= atomicAdd(group_count, subgroup_count); //
88 subgroupMemoryBarrierShared();
89 // propager offset dans les autres threads du sous groupe
90 offset= subgroup_offset + subgroupBroadcast(offset, 0);
91
92 // 2. reserver une place pour les resultats du groupe dans le buffer
93 // 1 addition atomique par groupe
94 if(gl_LocalInvocationIndex == 0)
95 group_offset= atomicAdd(count, group_count);
96 barrier();
97
98 // 3. ecrire les resultats
99 if(subgroupBallotBitExtract(mask, gl_SubgroupInvocationID))
100 // ecrit la valeur lorsqu'elle verifie la condition
101 b[offset + group_offset]= a[ID];
102 // toutes les valeurs d'un groupe sont ecrites en sequence dans le buffer resultat
103}
104
105#endif