Skip to content

Commit 9a1c347

Browse files
author
devsh
committed
don't bitcast when doing OpAccessChain
start implementing struct-member-traits extend `nbl::hlsl::mpl` add a `nbl::hlsl::size_of`
1 parent eba922c commit 9a1c347

File tree

3 files changed

+114
-12
lines changed

3 files changed

+114
-12
lines changed

include/nbl/builtin/hlsl/bda/__ref.hlsl

Lines changed: 67 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#define _NBL_BUILTIN_HLSL_BDA_REF_INCLUDED_
66

77
#include "nbl/builtin/hlsl/functional.hlsl"
8+
#include "nbl/builtin/hlsl/mpl.hlsl"
89

910
namespace nbl
1011
{
@@ -26,6 +27,69 @@ struct __spv_ptr_t<T,true>
2627
[[vk::ext_decorate(spv::DecorationRestrictPointer)]] spirv::bda_pointer_t<T> value;
2728
};
2829

30+
31+
// silly utility traits
32+
template<typename T>
33+
struct member_count
34+
{
35+
NBL_CONSTEXPR_STATIC_INLINE uint32_t value = 0;
36+
};
37+
template<typename T>
38+
NBL_CONSTEXPR uint32_t member_count_v = member_count<T>::value;
39+
40+
template<typename T, int32_t MemberIx>
41+
struct member_type;
42+
template<typename T, int32_t MemberIx>
43+
using member_type_t = typename member_type<T,MemberIx>::type;
44+
45+
// default alignment is the alignment of the type
46+
template<typename T, int32_t MemberIx>
47+
struct member_alignment
48+
{
49+
NBL_CONSTEXPR_STATIC_INLINE uint32_t value = alignment_of_v<member_type_t<T,MemberIx> >;
50+
};
51+
template<typename T, int32_t MemberIx>
52+
NBL_CONSTEXPR uint32_t member_alignment_v = member_alignment<T,MemberIx>::value;
53+
54+
namespace impl
55+
{
56+
template<typename T, uint32_t N>
57+
struct default_alignment
58+
{
59+
NBL_CONSTEXPR_STATIC_INLINE uint32_t value = mpl::max_v<uint32_t,member_alignment_v<T,N-1>,member_alignment_v<T,N-2> >;
60+
};
61+
template<typename T>
62+
struct default_alignment<T,1>
63+
{
64+
NBL_CONSTEXPR_STATIC_INLINE uint32_t value = member_alignment_v<T,0>;
65+
};
66+
// le invalid value
67+
template<typename T>
68+
struct default_alignment<T,0>
69+
{
70+
NBL_CONSTEXPR_STATIC_INLINE uint32_t value = 0;
71+
};
72+
template<typename T, typename MemberCount=member_count<T> >
73+
NBL_CONSTEXPR uint32_t default_alignment_v = default_alignment<T,MemberCount::value>::value;
74+
}
75+
76+
// the default specialization of the offset assumes scalar layout
77+
template<typename T, int32_t MemberIx>
78+
struct member_offset
79+
{
80+
// TODO: assert that the custom alignment is no less than the type's natural alignment?
81+
// first byte past previous member, rounded up to out alignment
82+
NBL_CONSTEXPR_STATIC_INLINE uint64_t value = mpl::align_up_v<member_offset<T,MemberIx-1>::value+size_of_v<member_type_t<T,MemberIx-1> >,member_alignment_v<T,MemberIx> >;
83+
};
84+
template<typename T>
85+
struct member_offset<T,0>
86+
{
87+
NBL_CONSTEXPR_STATIC_INLINE uint64_t value = 0;
88+
};
89+
template<typename T, int32_t MemberIx>
90+
NBL_CONSTEXPR uint64_t member_offset_v = member_offset<T,MemberIx>::value;
91+
92+
2993
template<typename T, uint32_t alignment, bool _restrict>
3094
struct __base_ref
3195
{
@@ -112,9 +176,9 @@ struct nbl::hlsl::bda::__ref<MyStruct,alignment,_restrict> : nbl::hlsl::bda::__b
112176
void __init(const nbl::hlsl::spirv::bda_pointer_t<MyStruct> _ptr)
113177
{
114178
base_t::__init(_ptr);
115-
a.__init(spirv::accessChain<float32_t>(base_t::__get_spv_ptr(),0));
116-
b.__init(spirv::accessChain<int32_t>(base_t::__get_spv_ptr(),1));
117-
c.__init(spirv::accessChain<int16_t2>(base_t::__get_spv_ptr(),2));
179+
a.__init(spirv::accessChain<float32_t>(base_t::ptr.value,0));
180+
b.__init(spirv::accessChain<int32_t>(base_t::ptr.value,1));
181+
c.__init(spirv::accessChain<int16_t2>(base_t::ptr.value,2));
118182
}
119183
};
120184
*/

include/nbl/builtin/hlsl/mpl.hlsl

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,35 +40,57 @@ struct countl_zero : impl::countl_zero<uint64_t(N), (sizeof(T) * 8)>
4040
{
4141
static_assert(is_integral<T>::value, "countl_zero type parameter must be an integral type");
4242
};
43+
template<class T, T N>
44+
NBL_CONSTEXPR T countl_zero_v = countl_zero<T,N>::value;
4345

4446
template<uint64_t X>
4547
struct log2
4648
{
4749
NBL_CONSTEXPR_STATIC_INLINE uint16_t value = X ? (1ull<<6)-countl_zero<uint64_t, X>::value-1 : -1ull;
4850
};
51+
template<uint64_t X>
52+
NBL_CONSTEXPR uint64_t log2_v = log2<X>::value;
4953

5054
template<typename T, T X, int32_t S>
5155
struct rotl
5256
{
53-
static const uint32_t N = 32u;
54-
static const int32_t r = S % N;
55-
static const T value = (S >= 0) ? ((X << r) | (X >> (N - r))) : (X >> (-r)) | (X << (N - (-r)));
57+
NBL_CONSTEXPR_STATIC_INLINE uint32_t N = 32u;
58+
NBL_CONSTEXPR_STATIC_INLINE int32_t r = S % N;
59+
NBL_CONSTEXPR_STATIC_INLINE T value = (S >= 0) ? ((X << r) | (X >> (N - r))) : (X >> (-r)) | (X << (N - (-r)));
5660
};
61+
template<typename T, T X, int32_t S>
62+
NBL_CONSTEXPR T rotl_v = rotl<T,X,S>::value;
5763

5864
template<typename T, T X, int32_t S>
5965
struct rotr
6066
{
61-
static const uint32_t N = 32u;
62-
static const int32_t r = S % N;
63-
static const T value = (S >= 0) ? ((X >> r) | (X << (N - r))) : (X << (-r)) | (X >> (N - (-r)));
67+
NBL_CONSTEXPR_STATIC_INLINE uint32_t N = 32u;
68+
NBL_CONSTEXPR_STATIC_INLINE int32_t r = S % N;
69+
NBL_CONSTEXPR_STATIC_INLINE T value = (S >= 0) ? ((X >> r) | (X << (N - r))) : (X << (-r)) | (X >> (N - (-r)));
70+
};
71+
template<typename T, T X, int32_t S>
72+
NBL_CONSTEXPR T rotr_v = rotr<T,X,S>::value;
73+
74+
template<uint64_t X, uint64_t M>
75+
struct align_up
76+
{
77+
NBL_CONSTEXPR_STATIC_INLINE uint64_t value = (X+M-1)/M;
6478
};
79+
template<uint64_t X, uint64_t M>
80+
NBL_CONSTEXPR uint64_t align_up_v = align_up<X,M>::value;
6581

6682
template<uint64_t N>
6783
struct is_pot : bool_constant< (N > 0 && !(N & (N - 1))) > {};
68-
6984
template<uint64_t N>
70-
NBL_CONSTEXPR_STATIC_INLINE bool is_pot_v = is_pot<N>::value;
85+
NBL_CONSTEXPR bool is_pot_v = is_pot<N>::value;
7186

87+
template<typename T, T X, T Y>
88+
struct max
89+
{
90+
NBL_CONSTEXPR_STATIC_INLINE T value = X<Y ? Y:X;
91+
};
92+
template<typename T, T X, T Y>
93+
NBL_CONSTEXPR T max_v = max<T,X,Y>::value;
7294
}
7395
}
7496
}

include/nbl/builtin/hlsl/type_traits.hlsl

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,13 @@ struct enable_if {};
390390
template<class T>
391391
struct enable_if<true, T> : type_identity<T> {};
392392

393+
// DXC sometimes doesn't report sizeof properly
394+
template<class T>
395+
struct size_of
396+
{
397+
NBL_CONSTEXPR_STATIC_INLINE uint64_t value = sizeof(T);
398+
};
399+
393400
template<class T>
394401
struct alignment_of;
395402

@@ -581,6 +588,13 @@ struct extent : std::extent<T, I> {};
581588
template<bool B, class T = void>
582589
using enable_if = std::enable_if<B, T>;
583590

591+
// DXC sometimes doesn't report sizeof properly
592+
template<class T>
593+
struct size_of
594+
{
595+
constexpr static inline uint64_t value = sizeof(T);
596+
};
597+
584598
template<class T>
585599
using alignment_of = std::alignment_of<T>;
586600

@@ -623,6 +637,8 @@ NBL_CONSTEXPR bool is_signed_v = is_signed<T>::value;
623637
template<class T>
624638
NBL_CONSTEXPR bool is_scalar_v = is_scalar<T>::value;
625639
template<class T>
640+
NBL_CONSTEXPR uint64_t size_of_v = size_of<T>::value;
641+
template<class T>
626642
NBL_CONSTEXPR uint32_t alignment_of_v = alignment_of<T>::value;
627643
template<class T, uint32_t N = 0>
628644
NBL_CONSTEXPR uint64_t extent_v = extent<T, N>::value;
@@ -788,7 +804,7 @@ struct extent<matrix<T, N, M>, 1> : integral_constant<uint64_t, M> {};
788804
// deal with typetraits, for now we rely on Clang/DXC internal __decltype(), if it breaks we revert to commit e4ab38ca227b15b2c79641c39161f1f922b779a3
789805
#ifdef __HLSL_VERSION
790806

791-
#define alignof(expr) ::nbl::hlsl::alignment_of<__decltype(expr)>::value
807+
#define alignof(expr) ::nbl::hlsl::alignment_of_v<__decltype(expr)>
792808

793809
// shoudl really return a std::type_info like struct or something, but no `constexpr` and unsure whether its possible to have a `const static SomeStruct` makes it hard to do...
794810
#define typeid(expr) (::nbl::hlsl::impl::typeid_t<__decltype(expr)>::value)

0 commit comments

Comments
 (0)