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