Skip to content

Commit 8e61632

Browse files
Create algorithm.hlsl
1 parent 382d955 commit 8e61632

File tree

1 file changed

+153
-0
lines changed

1 file changed

+153
-0
lines changed
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
// Copyright (C) 2022 - DevSH Graphics Programming Sp. z O.O.
2+
// This file is part of the "Nabla Engine".
3+
// For conditions of distribution and use, see copyright notice in nabla.h
4+
#ifndef _NBL_BUILTIN_HLSL_ALGORITHM_INCLUDED_
5+
#define _NBL_BUILTIN_HLSL_ALGORITHM_INCLUDED_
6+
7+
namespace nbl
8+
{
9+
namespace hlsl
10+
{
11+
12+
13+
namespace impl
14+
{
15+
16+
// TODO: move this to some other header
17+
bool isNPoT(const uint x)
18+
{
19+
return x&(x-1);
20+
}
21+
22+
template<class Accessor, class Comparator>
23+
struct bound_t
24+
{
25+
static bound_t<Accessor,Comparator> setup(uint begin, const uint end, const typename Accessor::value_type _value, const Comparator _comp)
26+
{
27+
bound_t<Accessor,Comparator> retval;
28+
retval.comp = _comp;
29+
retval.value = _value;
30+
retval.it = begin;
31+
retval.len = end-begin;
32+
return retval;
33+
}
34+
35+
36+
uint operator()(inout Accessor accessor)
37+
{
38+
if (isNPoT(len))
39+
{
40+
const uint newLen = 0x1u<<firstbithigh(len);
41+
const uint testPoint = it+(len-newLen);
42+
len = newLen;
43+
comp_step(accessor,testPoint);
44+
}
45+
while (len)
46+
{
47+
// could unroll 3 times or more
48+
iteration(accessor);
49+
iteration(accessor);
50+
}
51+
comp_step(accessor,it,it+1u);
52+
return it;
53+
}
54+
55+
void iteration(inout Accessor accessor)
56+
{
57+
len >>= 1;
58+
const uint mid = it+len;
59+
comp_step(accessor,mid);
60+
}
61+
62+
void comp_step(inout Accessor accessor, const uint testPoint, const uint rightBegin)
63+
{
64+
if (comp(accessor[testPoint],value))
65+
it = rightBegin;
66+
}
67+
void comp_step(inout Accessor accessor, const uint testPoint)
68+
{
69+
comp_step(accessor,testPoint,testPoint);
70+
}
71+
72+
Comparator comp;
73+
typename Accessor::value_type value;
74+
uint it;
75+
uint len;
76+
};
77+
78+
template<class Accessor, class Comparator>
79+
struct lower_to_upper_comparator_transform_t
80+
{
81+
bool operator()(const typename Accessor::value_type lhs, const typename Accessor::value_type rhs)
82+
{
83+
return !comp(rhs,lhs);
84+
}
85+
86+
Comparator comp;
87+
};
88+
89+
}
90+
91+
92+
template<class Accessor, class Comparator>
93+
uint lower_bound(inout Accessor accessor, const uint begin, const uint end, const typename Accessor::value_type value, const Comparator comp)
94+
{
95+
impl::bound_t<Accessor,Comparator> implementation = impl::bound_t<Accessor,Comparator>::setup(begin,end,value,comp);
96+
return implementation(accessor);
97+
}
98+
99+
template<class Accessor, class Comparator>
100+
uint upper_bound(inout Accessor accessor, const uint begin, const uint end, const typename Accessor::value_type value, const Comparator comp)
101+
{
102+
using TransformedComparator = impl::lower_to_upper_comparator_transform_t<Accessor,Comparator>;
103+
TransformedComparator transformedComparator;
104+
transformedComparator.comp = comp;
105+
return lower_bound<Accessor,TransformedComparator>(accessor,begin,end,value,transformedComparator);
106+
}
107+
108+
109+
namespace impl
110+
{
111+
112+
template<typename T>
113+
struct comparator_lt_t
114+
{
115+
bool operator()(const T lhs, const T rhs)
116+
{
117+
return lhs<rhs;
118+
}
119+
};
120+
121+
// extra indirection due to https://github.com/microsoft/DirectXShaderCompiler/issues/4771
122+
template<class Accessor, typename T>
123+
uint lower_bound(inout Accessor accessor, const uint begin, const uint end, const T value)
124+
{
125+
using Comparator = impl::comparator_lt_t<T>;
126+
Comparator comp;
127+
return nbl::hlsl::lower_bound<Accessor,Comparator>(accessor,begin,end,value,comp);
128+
}
129+
template<class Accessor, typename T>
130+
uint upper_bound(inout Accessor accessor, const uint begin, const uint end, const T value)
131+
{
132+
using Comparator = impl::comparator_lt_t<T>;
133+
Comparator comp;
134+
return nbl::hlsl::upper_bound<Accessor,Comparator>(accessor,begin,end,value,comp);
135+
}
136+
137+
}
138+
139+
template<class Accessor>
140+
uint lower_bound(inout Accessor accessor, const uint begin, const uint end, const typename Accessor::value_type value)
141+
{
142+
return impl::lower_bound<Accessor,typename Accessor::value_type>(accessor,begin,end,value);
143+
}
144+
template<class Accessor>
145+
uint upper_bound(inout Accessor accessor, const uint begin, const uint end, const typename Accessor::value_type value)
146+
{
147+
return impl::upper_bound<Accessor,typename Accessor::value_type>(accessor,begin,end,value);
148+
}
149+
150+
}
151+
}
152+
153+
#endif

0 commit comments

Comments
 (0)