1
+ // Copyright (C) 2018-2024 - 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_BDA_STRUCT_DECLARE_INCLUDED_
5
+ #define _NBL_BUILTIN_HLSL_BDA_STRUCT_DECLARE_INCLUDED_
6
+
7
+ #include "nbl/builtin/hlsl/mpl.hlsl"
8
+
9
+ namespace nbl
10
+ {
11
+ namespace hlsl
12
+ {
13
+ namespace bda
14
+ {
15
+ // silly utility traits
16
+ template<typename T>
17
+ struct member_count
18
+ {
19
+ NBL_CONSTEXPR_STATIC_INLINE uint32_t value = 0 ;
20
+ };
21
+ template<typename T>
22
+ NBL_CONSTEXPR uint32_t member_count_v = member_count<T>::value;
23
+
24
+ template<typename T, int32_t MemberIx>
25
+ struct member_type;
26
+ template<typename T, int32_t MemberIx>
27
+ using member_type_t = typename member_type<T,MemberIx>::type;
28
+
29
+ // default alignment is the alignment of the type
30
+ template<typename T, int32_t MemberIx>
31
+ struct member_alignment
32
+ {
33
+ NBL_CONSTEXPR_STATIC_INLINE uint32_t value = alignment_of_v<member_type_t<T,MemberIx> >;
34
+ };
35
+ template<typename T, int32_t MemberIx>
36
+ NBL_CONSTEXPR uint32_t member_alignment_v = member_alignment<T,MemberIx>::value;
37
+
38
+ // the default specialization of the offset assumes scalar layout
39
+ template<typename T, int32_t MemberIx>
40
+ struct member_offset
41
+ {
42
+ // TODO: assert that the custom alignment is no less than the type's natural alignment?
43
+ // first byte past previous member, rounded up to out alignment
44
+ 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> >;
45
+ };
46
+ template<typename T>
47
+ struct member_offset<T,0 >
48
+ {
49
+ NBL_CONSTEXPR_STATIC_INLINE uint64_t value = 0 ;
50
+ };
51
+ template<typename T, int32_t MemberIx>
52
+ NBL_CONSTEXPR uint64_t member_offset_v = member_offset<T,MemberIx>::value;
53
+
54
+ // stuff needed to compute alignment of the struct properly
55
+ #ifdef __HLSL_VERSION
56
+ namespace impl
57
+ {
58
+ template<typename T, uint32_t N>
59
+ struct default_alignment
60
+ {
61
+ NBL_CONSTEXPR_STATIC_INLINE uint32_t value = mpl::max_v<uint32_t,member_alignment_v<T,N-1 >,member_alignment_v<T,N-2 > >;
62
+ };
63
+ template<typename T>
64
+ struct default_alignment<T,1 >
65
+ {
66
+ NBL_CONSTEXPR_STATIC_INLINE uint32_t value = member_alignment_v<T,0 >;
67
+ };
68
+ // le invalid value
69
+ template<typename T>
70
+ struct default_alignment<T,0 >
71
+ {
72
+ NBL_CONSTEXPR_STATIC_INLINE uint32_t value = 0 ;
73
+ };
74
+ template<typename T, typename MemberCount=member_count<T> >
75
+ NBL_CONSTEXPR uint32_t default_alignment_v = default_alignment<T,MemberCount::value>::value;
76
+ }
77
+ #endif
78
+ }
79
+ }
80
+ }
81
+
82
+ // time for some macros!
83
+ // need to gen identical struct in HLSL and C++
84
+ #if 0
85
+ // forward declaration - outside of macro
86
+ struct MyStruct;
87
+
88
+ // TODO: to be generated by a BOOST_PP macro:
89
+ // - take template parameters list
90
+ // - take partial spec name
91
+ // - custom alignas on the struct or not
92
+ // - sequence of variable name and type (identifier0,Type0)...(identifierN,TypeN)
93
+
94
+ template</*T_ARGS*/ >
95
+ struct ::nbl::hlsl::bda::member_count<MyStruct >
96
+ {
97
+ NBL_CONSTEXPR_STATIC_INLINE uint32_t value = 3 ;
98
+ };
99
+ template</*T_ARGS*/ >
100
+ struct ::nbl::hlsl::bda::member_type<MyStruct,0 >
101
+ {
102
+ using type = float32_t;
103
+ };
104
+ template</*T_ARGS*/ >
105
+ struct ::nbl::hlsl::bda::member_type<MyStruct,1 >
106
+ {
107
+ using type = int32_t;
108
+ };
109
+ template</*T_ARGS*/ >
110
+ struct ::nbl::hlsl::bda::member_type<MyStruct,2 >
111
+ {
112
+ using type = int16_t2;
113
+ };
114
+ // self alignment
115
+ #define NBL_ALIGNAS 8
116
+ template<>
117
+ struct ::nbl::hlsl::alignment_of<MyStruct >
118
+ {
119
+ NBL_CONSTEXPR_STATIC_INLINE uint32_t value = ::nbl::hlsl::conditional_value<NBL_ALIGNAS!=0 ,uint32_t,NBL_ALIGNAS,::nbl::hlsl::bda::impl::default_alignment_v<MyStruct > >::value;
120
+ };
121
+ template<>
122
+ struct ::nbl::hlsl::size_of<MyStruct >
123
+ {
124
+ NBL_CONSTEXPR_STATIC_INLINE uint32_t __last_member_ix_v = ::nbl::hlsl::bda::member_count_v<MyStruct >-1 ;
125
+ NBL_CONSTEXPR_STATIC_INLINE uint64_t __last_member_offset_v = ::nbl::hlsl::bda::member_offset_v<MyStruct,__last_member_ix_v>;
126
+ NBL_CONSTEXPR_STATIC_INLINE uint64_t __last_member_size_v = ::nbl::hlsl::size_of_v<::nbl::hlsl::bda::member_type_t<MyStruct,__last_member_ix_v> >;
127
+ NBL_CONSTEXPR_STATIC_INLINE uint32_t value = mpl::align_up_v<__last_member_offset_v+__last_member_size_v,alignment_of_v<MyStruct > >;
128
+ };
129
+ #ifdef __HLSL_VERSION
130
+ /*template<T_ARGS>*/
131
+ struct MyStruct
132
+ {
133
+ [[vk::ext_decorate (spv::DecorationOffset,::nbl::hlsl::bda::member_offset_v<MyStruct,0 >)]] float32_t a;
134
+ [[vk::ext_decorate (spv::DecorationOffset,::nbl::hlsl::bda::member_offset_v<MyStruct,1 >)]] int32_t b;
135
+ [[vk::ext_decorate (spv::DecorationOffset,::nbl::hlsl::bda::member_offset_v<MyStruct,2 >)]] int16_t2 c;
136
+ };
137
+ template<uint32_t alignment, bool _restrict/*, T_ARGS*/ >
138
+ struct nbl::hlsl::bda::__ref<MyStruct,alignment,_restrict> : nbl::hlsl::bda::__base_ref<MyStruct,alignment,_restrict>
139
+ {
140
+ using base_t = __base_ref<MyStruct,alignment,_restrict>;
141
+ using this_t = __ref<MyStruct,alignment,_restrict>;
142
+
143
+ ::nbl::hlsl::bda::__ref<float32_t,::nbl::hlsl::mpl::min_v<uint32_t,::nbl::hlsl::bda::member_alignment_v<MyStruct,0 >,alignment>,_restrict> a;
144
+ ::nbl::hlsl::bda::__ref<int32_t,::nbl::hlsl::mpl::min_v<uint32_t,::nbl::hlsl::bda::member_alignment_v<MyStruct,1 >,alignment>,_restrict> b;
145
+ ::nbl::hlsl::bda::__ref<int16_t2,::nbl::hlsl::mpl::min_v<uint32_t,::nbl::hlsl::bda::member_alignment_v<MyStruct,2 >,alignment>,_restrict> c;
146
+
147
+ void __init (const ::nbl::hlsl::spirv::bda_pointer_t<MyStruct > _ptr)
148
+ {
149
+ base_t::__init (_ptr);
150
+ a.__init (::nbl::hlsl::spirv::accessChain<float32_t>(base_t::ptr.value,0 ));
151
+ b.__init (::nbl::hlsl::spirv::accessChain<int32_t>(base_t::ptr.value,1 ));
152
+ c.__init (::nbl::hlsl::spirv::accessChain<int16_t2>(base_t::ptr.value,2 ));
153
+ }
154
+ };
155
+ #else
156
+ /*template<T_ARGS>*/
157
+ struct /*alignas(NBL_ALIGNAS)*/ MyStruct
158
+ {
159
+ alignas (::nbl::hlsl::bda::member_alignment_v<MyStruct,0 >) float32_t a;
160
+ alignas (::nbl::hlsl::bda::member_alignment_v<MyStruct,1 >) int32_t b;
161
+ alignas (::nbl::hlsl::bda::member_alignment_v<MyStruct,2 >) int16_t2 c;
162
+ };
163
+ #endif
164
+ #endif
165
+
166
+ #endif
0 commit comments