gKit2 light
Toggle main menu visibility
Loading...
Searching...
No Matches
gkit2_tutos
M2
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
12
layout( std430, binding= 0 ) buffer inputData
13
{
14
int
a[];
15
};
16
17
layout( std430, binding= 1 ) buffer outputData
18
{
19
int
b[];
20
};
21
22
layout( std430, binding= 2 ) buffer countData
23
{
24
uint count;
25
};
26
27
uniform
int
v= 5;
28
29
shared uint group_count;
30
shared uint group_offset;
31
32
layout( local_size_x=256 ) in;
33
void
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
Generated on
for gKit2 light by
1.17.0