Skip to content

Commit 3359e34

Browse files
committed
- Make most of intutil shared, deprecate the versions that were in the.h
that moved to .hlsl - Update the GLSL bitreverse to be in-line with the GLSL spec
1 parent a933953 commit 3359e34

File tree

8 files changed

+173
-156
lines changed

8 files changed

+173
-156
lines changed

include/nbl/builtin/hlsl/cpp_compat/basic.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ inline To _static_cast(From v)
4141
#define NBL_CONSTEXPR_STATIC constexpr static
4242
#define NBL_CONSTEXPR_STATIC_INLINE constexpr static inline
4343
#define NBL_CONSTEXPR_INLINE_FUNC constexpr inline
44+
#define NBL_CONSTEXPR_FORCED_INLINE_FUNC NBL_FORCE_INLINE constexpr
4445
#define NBL_CONST_MEMBER_FUNC const
4546

4647
namespace nbl::hlsl
@@ -70,6 +71,7 @@ namespace nbl::hlsl
7071
#define NBL_CONSTEXPR_STATIC const static
7172
#define NBL_CONSTEXPR_STATIC_INLINE const static
7273
#define NBL_CONSTEXPR_INLINE_FUNC inline
74+
#define NBL_CONSTEXPR_FORCED_INLINE_FUNC inline
7375
#define NBL_CONST_MEMBER_FUNC
7476

7577
namespace nbl

include/nbl/builtin/hlsl/fft/common.hlsl

Lines changed: 33 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
#include <nbl/builtin/hlsl/cpp_compat.hlsl>
55
#include <nbl/builtin/hlsl/complex.hlsl>
66
#include <nbl/builtin/hlsl/concepts.hlsl>
7-
8-
#ifndef __HLSL_VERSION
9-
#include <nbl/core/math/intutil.h>
7+
#include <nbl/builtin/hlsl/math/intutil.hlsl>
8+
#include "nbl/builtin/hlsl/numbers.hlsl"
9+
#include "nbl/builtin/hlsl/concepts.hlsl"
1010

1111
namespace nbl
1212
{
@@ -25,7 +25,7 @@ inline vector<uint64_t, 3> padDimensions(NBL_CONST_REF_ARG(vector<uint32_t, N>)
2525
uint16_t axisCount = 0;
2626
for (uint16_t i = 0u; i < M; i++)
2727
{
28-
newDimensions[i] = core::roundUpToPoT(newDimensions[i]);
28+
newDimensions[i] = hlsl::roundUpToPoT(newDimensions[i]);
2929
if (realFFT && !axisCount++)
3030
newDimensions[i] /= 2;
3131
}
@@ -43,57 +43,40 @@ inline uint64_t getOutputBufferSize(NBL_CONST_REF_ARG(vector<uint32_t, N>) input
4343
return numberOfComplexElements * (halfFloats ? sizeof(complex_t<float16_t>) : sizeof(complex_t<float32_t>));
4444
}
4545

46-
47-
}
48-
}
49-
}
50-
51-
#else
52-
53-
#include "nbl/builtin/hlsl/numbers.hlsl"
54-
#include "nbl/builtin/hlsl/concepts.hlsl"
55-
56-
namespace nbl
57-
{
58-
namespace hlsl
59-
{
60-
namespace fft
61-
{
62-
6346
// Computes the kth element in the group of N roots of unity
6447
// Notice 0 <= k < N/2, rotating counterclockwise in the forward (DIF) transform and clockwise in the inverse (DIT)
6548
template<bool inverse, typename Scalar>
6649
complex_t<Scalar> twiddle(uint32_t k, uint32_t halfN)
6750
{
6851
complex_t<Scalar> retVal;
69-
const Scalar kthRootAngleRadians = numbers::pi<Scalar> * Scalar(k) / Scalar(halfN);
70-
retVal.real( cos(kthRootAngleRadians) );
71-
if (! inverse)
72-
retVal.imag( sin(-kthRootAngleRadians) );
52+
const Scalar kthRootAngleRadians = numbers::pi<Scalar> *Scalar(k) / Scalar(halfN);
53+
retVal.real(cos(kthRootAngleRadians));
54+
if (!inverse)
55+
retVal.imag(sin(-kthRootAngleRadians));
7356
else
74-
retVal.imag( sin(kthRootAngleRadians) );
75-
return retVal;
57+
retVal.imag(sin(kthRootAngleRadians));
58+
return retVal;
7659
}
7760

78-
template<bool inverse, typename Scalar>
79-
struct DIX
80-
{
61+
template<bool inverse, typename Scalar>
62+
struct DIX
63+
{
8164
static void radix2(NBL_CONST_REF_ARG(complex_t<Scalar>) twiddle, NBL_REF_ARG(complex_t<Scalar>) lo, NBL_REF_ARG(complex_t<Scalar>) hi)
8265
{
8366
plus_assign< complex_t<Scalar> > plusAss;
8467
//Decimation in time - inverse
8568
if (inverse) {
8669
complex_t<Scalar> wHi = twiddle * hi;
8770
hi = lo - wHi;
88-
plusAss(lo, wHi);
71+
plusAss(lo, wHi);
8972
}
9073
//Decimation in frequency - forward
9174
else {
9275
complex_t<Scalar> diff = lo - hi;
9376
plusAss(lo, hi);
94-
hi = twiddle * diff;
77+
hi = twiddle * diff;
9578
}
96-
}
79+
}
9780
};
9881

9982
template<typename Scalar>
@@ -113,11 +96,27 @@ void unpack(NBL_REF_ARG(complex_t<Scalar>) lo, NBL_REF_ARG(complex_t<Scalar>) hi
11396
lo = x;
11497
}
11598

99+
100+
}
101+
}
102+
}
103+
104+
#ifdef __HLSL_VERSION
105+
106+
namespace nbl
107+
{
108+
namespace hlsl
109+
{
110+
namespace fft
111+
{
112+
113+
// ------------------------------------------------- Utils ---------------------------------------------------------
114+
116115
// Bit-reverses T as a binary string of length given by Bits
117116
template<typename T, uint16_t Bits NBL_FUNC_REQUIRES(is_integral_v<T> && Bits <= sizeof(T) * 8)
118117
T bitReverse(T value)
119118
{
120-
return glsl::bitfieldReverse<uint32_t>(value) >> (sizeof(T) * 8 - Bits);
119+
return spirv::bitReverse<uint32_t>(value) >> (sizeof(T) * 8 - Bits);
121120
}
122121

123122
}

include/nbl/builtin/hlsl/glsl_compat/core.hlsl

Lines changed: 14 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ genIUType bitfieldInsert(genIUType const& Base, genIUType const& Insert, int Off
3131
return glm::bitfieldInsert<genIUType>(Base, Insert, Offset, Bits);
3232
}
3333

34+
template<typename genIUType>
35+
genIUType bitfieldReverse(genIUType const& Value)
36+
{
37+
return glm::bitfieldReverse<genIUType>(Value);
38+
}
39+
3440
#else
3541
/**
3642
* Generic SPIR-V
@@ -136,61 +142,6 @@ float32_t2 unpackSnorm2x16(uint32_t p)
136142
return spirv::unpackSnorm2x16(p);
137143
}
138144

139-
// No better way to get a vector type of same length as Integral but made up of `int32_t` s?
140-
141-
template<typename T>
142-
vector<int32_t, uint32_t(sizeof(T) / sizeof(scalar_type_t<T>))> findLSB(T value)
143-
{
144-
using return_t = vector<int32_t, uint32_t(sizeof(T) / sizeof(scalar_type_t<T>))>;
145-
return bit_cast<return_t, T>(spirv::findILsb<T>(value));
146-
}
147-
148-
namespace impl
149-
{
150-
template<typename T, bool isSigned, bool isIntegral>
151-
struct findMSB {};
152-
153-
template<typename T, bool isSigned>
154-
struct findMSB<T, isSigned, false>
155-
{
156-
using return_t = vector<int32_t, uint32_t(sizeof(T) / sizeof(scalar_type_t<T>))>;
157-
158-
static return_t __call(T value)
159-
{
160-
static_assert(is_integral<T>::value, "T is not an integral type!");
161-
return value;
162-
}
163-
};
164-
165-
template<typename T>
166-
struct findMSB<T, true, true>
167-
{
168-
using return_t = vector<int32_t, uint32_t(sizeof(T) / sizeof(scalar_type_t<T>))>;
169-
170-
static return_t __call(T value)
171-
{
172-
return bit_cast<return_t, T>(spirv::findSMsb<T>(value));
173-
}
174-
};
175-
176-
template<typename T>
177-
struct findMSB<T, false, true>
178-
{
179-
using return_t = vector<int32_t, uint32_t(sizeof(T) / sizeof(scalar_type_t<T>))>;
180-
181-
static return_t __call(T value)
182-
{
183-
return bit_cast<return_t, T>(spirv::findUMsb<T>(value));
184-
}
185-
};
186-
} // namespace impl
187-
188-
template<typename T>
189-
vector<int32_t, uint32_t(sizeof(T) / sizeof(scalar_type_t<T>))> findMSB(T value)
190-
{
191-
return impl::findMSB<T, is_signed_v<T>, is_integral_v<T> >::__call(value);
192-
}
193-
194145
/**
195146
* For Vertex Shaders
196147
*/
@@ -275,10 +226,17 @@ T bitfieldInsert(T base, T insert, uint32_t offset, uint32_t bits)
275226
return spirv::bitFieldInsert<T>(base, insert, offset, bits);
276227
}
277228

229+
// Spec requires this to return the bitreversal done with the amount of bits necessary to represent the number https://registry.khronos.org/OpenGL-Refpages/gl4/html/bitfieldReverse.xhtml
278230
template<typename T>
279231
T bitfieldReverse(T value)
280232
{
281-
return spirv::bitFieldReverse<T>(value);
233+
using unsigned_t = typename make_unsigned<T>::type;
234+
// Bit-cast to uint to use the uint version of MSB
235+
unsigned_t unsignedCasted = spirv::bitcast<unsigned_t, T>(value);
236+
unsigned_t bits = findMSB(unsignedCasted);
237+
NBL_CONSTEXPR_STATIC_INLINE unsigned_t width = promote<unsigned_t, scalar_type_t<unsigned_t> >(scalar_type_t<unsigned_t>(sizeof(scalar_type_t<unsigned_t>)));
238+
// Do the shift in unsigned to ensure we do not get an arithmetic shift if signed, then cast back to original type
239+
return spirv::bitcast<T, unsigned_t>(spirv::bitReverse<unsigned_t>(unsignedCasted) >> (width - bits));
282240
}
283241

284242
#endif
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
#ifndef _NBL_BUILTIN_HLSL_MATH_INTUTIL_INCLUDED_
2+
#define _NBL_BUILTIN_HLSL_MATH_INTUTIL_INCLUDED_
3+
4+
#include "nbl/builtin/hlsl/cpp_compat.hlsl"
5+
#include "nbl/builtin/hlsl/type_traits.hlsl"
6+
7+
namespace nbl
8+
{
9+
namespace hlsl
10+
{
11+
12+
template<typename Integer NBL_FUNC_REQUIRES(is_integral_v<Integer>)
13+
NBL_CONSTEXPR_FORCED_INLINE_FUNC bool isNPoT(Integer value)
14+
{
15+
return value & (value - Integer(1));
16+
}
17+
18+
template<typename Integer NBL_FUNC_REQUIRES(is_integral_v<Integer>)
19+
NBL_CONSTEXPR_FORCED_INLINE_FUNC bool isPoT(Integer value)
20+
{
21+
return !isNPoT<Integer>(value);
22+
}
23+
24+
25+
template<typename Integer NBL_FUNC_REQUIRES(is_integral_v<Integer>)
26+
NBL_CONSTEXPR_FORCED_INLINE_FUNC Integer roundUpToPoT(Integer value)
27+
{
28+
return Integer(0x1u) << Integer(1 + hlsl::findMSB<Integer>(value - Integer(1))); // this wont result in constexpr because findMSB is not one
29+
}
30+
31+
template<typename Integer NBL_FUNC_REQUIRES(is_integral_v<Integer>)
32+
NBL_CONSTEXPR_FORCED_INLINE_FUNC Integer roundDownToPoT(Integer value)
33+
{
34+
return Integer(0x1u) << hlsl::findMSB<Integer>(value);
35+
}
36+
37+
template<typename Integer NBL_FUNC_REQUIRES(is_integral_v<Integer>)
38+
NBL_CONSTEXPR_FORCED_INLINE_FUNC Integer roundUp(Integer value, Integer multiple)
39+
{
40+
Integer tmp = (value + multiple - 1u) / multiple;
41+
return tmp * multiple;
42+
}
43+
44+
template<typename Integer NBL_FUNC_REQUIRES(is_integral_v<Integer>)
45+
NBL_CONSTEXPR_FORCED_INLINE_FUNC Integer align(Integer alignment, Integer size, NBL_REF_ARG(Integer) address, NBL_REF_ARG(Integer) space)
46+
{
47+
Integer nextAlignedAddr = roundUp<Integer>(address, alignment);
48+
49+
Integer spaceDecrement = nextAlignedAddr - address;
50+
if (spaceDecrement > space)
51+
return 0u;
52+
53+
Integer newSpace = space - spaceDecrement;
54+
if (size > newSpace)
55+
return 0u;
56+
57+
space = newSpace;
58+
return address = nextAlignedAddr;
59+
}
60+
61+
#ifndef __HLSL_VERSION
62+
63+
// Have to wait for the HLSL patch for `is_enum`. Would also have to figure out how to do it without initializer lists for HLSL use.
64+
65+
//! Get bitmask from variadic arguments passed.
66+
/*
67+
For example if you were to create bitmask for vertex attributes
68+
having positions inteeger set as 0, colors as 1 and normals
69+
as 3, just pass them to it and use the value returned.
70+
*/
71+
72+
template<typename BitmaskType NBL_FUNC_REQUIRES(is_integral_v<BitmaskType> || std::is_enum_v<BitmaskType>)
73+
NBL_CONSTEXPR_FORCED_INLINE_FUNC uint64_t createBitmask(std::initializer_list<BitmaskType> initializer)
74+
{
75+
uint64_t retval{};
76+
for (const auto& it : initializer)
77+
retval |= (1ull << it);
78+
return retval;
79+
}
80+
81+
#endif
82+
83+
} // end namespace hlsl
84+
} // end namespace nbl
85+
86+
87+
#endif
88+

include/nbl/builtin/hlsl/spirv_intrinsics/core.hlsl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ enable_if_t<is_integral_v<Integral>, Integral> bitFieldInsert( Integral base, In
232232

233233
template<typename Integral>
234234
[[vk::ext_instruction( spv::OpBitReverse )]]
235-
enable_if_t<is_integral_v<Integral>, Integral> bitFieldReverse( Integral base );
235+
enable_if_t<is_integral_v<Integral>, Integral> bitReverse( Integral base );
236236

237237
template<typename FloatingPoint>
238238
[[vk::ext_instruction( spv::OpIsNan )]]

0 commit comments

Comments
 (0)