Skip to content

Commit 36473e3

Browse files
committed
Port and refactor virtual_workgroup.hlsl
1 parent 045a5ae commit 36473e3

File tree

1 file changed

+91
-0
lines changed

1 file changed

+91
-0
lines changed
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
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

Comments
 (0)