1
+ #ifndef _NBL_HLSL_SCAN_VIRTUAL_WORKGROUP_INCLUDED_
2
+ #define _NBL_HLSL_SCAN_VIRTUAL_WORKGROUP_INCLUDED_
3
+
4
+ // TODO (PentaKon): Decide if these are needed once we have a clearer picture of the refactor
5
+ #include <nbl/builtin/hlsl/limits/numeric.hlsl>
6
+ #include <nbl/builtin/hlsl/math/typeless_arithmetic.hlsl>
7
+ #include <nbl/builtin/hlsl/workgroup/arithmetic.hlsl> // This is where all the nbl_glsl_workgroupOPs are defined
8
+ #include <nbl/builtin/hlsl/scan/declarations.hlsl>
9
+
10
+ #include <nbl/builtin/hlsl/binops.hlsl>
11
+
12
+ const uint gl_LocalInvocationIndex: SV_GroupIndex ;
13
+
14
+ namespace nbl
15
+ {
16
+ namespace hlsl
17
+ {
18
+ namespace scan
19
+ {
20
+ template<class Binop, class Storage_t>
21
+ void virtualWorkgroup (in uint treeLevel, in uint localWorkgroupIndex)
22
+ {
23
+ Binop binop;
24
+ const Parameters_t params = getParameters ();
25
+ const uint levelInvocationIndex = localWorkgroupIndex * _NBL_HLSL_WORKGROUP_SIZE_ + gl_LocalInvocationIndex;
26
+ const bool lastInvocationInGroup = gl_LocalInvocationIndex == (_NBL_HLSL_WORKGROUP_SIZE_ - 1 );
27
+
28
+ const uint lastLevel = params.topLevel << 1u;
29
+ const uint pseudoLevel = levelInvocationIndex <= params.lastElement[pseudoLevel];
30
+
31
+ const bool inRange = levelInvocationIndex <= params.lastElement[pseudoLevel];
32
+
33
+ Storage_t data = binop::identity ();
34
+ if (inRange)
35
+ {
36
+ getData (data, levelInvocationIndex, localWorkgroupIndex, treeLevel, pseudoLevel);
37
+ }
38
+
39
+ if (treeLevel < params.topLevel)
40
+ {
41
+ data = workgroup::reduction<binop>()(data);
42
+ }
43
+ // REVIEW: missing _TYPE_ check and extra case here
44
+ else if (treeLevel != params.topLevel)
45
+ {
46
+ data = workgroup::inclusive_scan<binop>()(data);
47
+ }
48
+ else
49
+ {
50
+ data = workgroup::exclusive_scan<binop>()(data);
51
+ }
52
+ setData (data, levelInvocationIndex, localWorkgroupIndex, treeLevel, pseudoLevel, inRange);
53
+ }
54
+ }
55
+ }
56
+ }
57
+
58
+ #ifndef _NBL_HLSL_SCAN_MAIN_DEFINED_ // TODO REVIEW: Are these needed, can this logic be refactored?
59
+ #include <nbl/builtin/hlsl/scan/default_scheduler.hlsl>
60
+ namespace nbl
61
+ {
62
+ namespace hlsl
63
+ {
64
+ namespace scan
65
+ {
66
+ DefaultSchedulerParameters_t getSchedulerParameters (); // this is defined in the final shader that assembles all the SCAN operation components
67
+ void main ()
68
+ {
69
+ const DefaultSchedulerParameters_t schedulerParams = getSchedulerParameters ();
70
+ const uint topLevel = getParameters ().topLevel;
71
+ // persistent workgroups
72
+ while (true )
73
+ {
74
+ uint treeLevel,localWorkgroupIndex;
75
+ if (scheduler::getWork (schedulerParams,topLevel,treeLevel,localWorkgroupIndex))
76
+ {
77
+ return ;
78
+ }
79
+
80
+ virtualWorkgroup (treeLevel,localWorkgroupIndex);
81
+
82
+ scheduler::markComplete (schedulerParams,topLevel,treeLevel,localWorkgroupIndex);
83
+ }
84
+ }
85
+ }
86
+ }
87
+ }
88
+ #define _NBL_HLSL_SCAN_MAIN_DEFINED_
89
+ #endif
90
+
91
+ #endif
0 commit comments