@@ -54,33 +54,8 @@ DEFINE_BUILTIN_VECTOR_SPECIALIZATION(float64_t, BUILTIN_VECTOR_SPECIALIZATION_RE
5454#undef BUILTIN_VECTOR_SPECIALIZATION_RET_VAL
5555#undef DEFINE_BUILTIN_VECTOR_SPECIALIZATION
5656
57- #ifdef __HLSL_VERSION
5857template<typename Integer>
5958struct find_msb_helper;
60- #else
61- // legacy code wouldn't work without it
62- template<typename Integer>
63- struct find_msb_helper
64- {
65- static int findMSB (NBL_CONST_REF_ARG (Integer) val)
66- {
67- if (is_signed_v<Integer>)
68- {
69- // GLM accepts only integer types, so idea is to cast input to integer type
70- using as_int = typename integer_of_size<sizeof (Integer)>::type;
71- const as_int valAsInt = reinterpret_cast<const as_int&>(val);
72- return glm::findMSB (valAsInt);
73- }
74- else
75- {
76- // GLM accepts only integer types, so idea is to cast input to integer type
77- using as_uint = typename unsigned_integer_of_size<sizeof (Integer)>::type;
78- const as_uint valAsUnsignedInt = reinterpret_cast<const as_uint&>(val);
79- return glm::findMSB (valAsUnsignedInt);
80- }
81- }
82- };
83- #endif
8459
8560template<>
8661struct find_msb_helper<uint32_t>
@@ -108,6 +83,50 @@ struct find_msb_helper<int32_t>
10883 }
10984};
11085
86+ #define DEFINE_FIND_MSB_COMMON_SPECIALIZATION (INPUT_INTEGER_TYPE, INTEGER_TYPE)\
87+ template<>\
88+ struct find_msb_helper<INPUT_INTEGER_TYPE>\
89+ {\
90+ static int32_t findMSB (NBL_CONST_REF_ARG (INPUT_INTEGER_TYPE) val)\
91+ {\
92+ return find_msb_helper<INTEGER_TYPE>::findMSB (val);\
93+ }\
94+ };\
95+
96+ DEFINE_FIND_MSB_COMMON_SPECIALIZATION (int16_t, int32_t)
97+ DEFINE_FIND_MSB_COMMON_SPECIALIZATION (uint16_t, uint32_t)
98+ #ifndef __HLSL_VERSION
99+ DEFINE_FIND_MSB_COMMON_SPECIALIZATION (int8_t, int32_t)
100+ DEFINE_FIND_MSB_COMMON_SPECIALIZATION (uint8_t, uint32_t)
101+ #endif
102+
103+ template<>
104+ struct find_msb_helper<uint64_t>
105+ {
106+ static int32_t findMSB (NBL_CONST_REF_ARG (uint64_t) val)
107+ {
108+ #ifdef __HLSL_VERSION
109+ const uint64_t lowBits = uint32_t (val);
110+ const uint64_t highBits = uint32_t (val >> 32 );
111+
112+ const int32_t lowMsb = findMSB (lowBits);
113+ if (lowMsb == -1 )
114+ {
115+ const uint64_t highBits = uint32_t (val >> 32 );
116+ const int32_t highMsb = findMSB (highBits);
117+ if (highBits == -1 )
118+ return -1 ;
119+ else
120+ return 32 + highMsb;
121+ }
122+
123+ return lowMsb;
124+ #else
125+ return glm::findMSB (val);
126+ #endif
127+ }
128+ };
129+
111130template<int N>
112131struct find_msb_helper<vector <uint32_t, N> >
113132{
@@ -134,42 +153,26 @@ struct find_msb_helper<vector<int32_t, N> >
134153 }
135154};
136155
137- #ifdef __HLSL_VERSION
138156template<typename Integer>
139157struct find_lsb_helper;
140- #else
141- // legacy code wouldn't work without it
142- template<typename Integer>
143- struct find_lsb_helper
158+
159+ template<>
160+ struct find_lsb_helper<int32_t>
144161{
145- static int32_t findLSB (NBL_CONST_REF_ARG (Integer ) val)
162+ static int32_t findLSB (NBL_CONST_REF_ARG (int32_t ) val)
146163 {
147164#ifdef __HLSL_VERSION
148165 return spirv::findILsb (val);
149166#else
150- if (is_signed_v<Integer>)
151- {
152- // GLM accepts only integer types, so idea is to cast input to integer type
153- using as_int = typename integer_of_size<sizeof (Integer)>::type;
154- const as_int valAsInt = reinterpret_cast<const as_int&>(val);
155- return glm::findLSB (valAsInt);
156- }
157- else
158- {
159- // GLM accepts only integer types, so idea is to cast input to integer type
160- using as_uint = typename unsigned_integer_of_size<sizeof (Integer)>::type;
161- const as_uint valAsUnsignedInt = reinterpret_cast<const as_uint&>(val);
162- return glm::findLSB (valAsUnsignedInt);
163- }
167+ return glm::findLSB (val);
164168#endif
165169 }
166170};
167- #endif
168171
169172template<>
170- struct find_lsb_helper<int32_t >
173+ struct find_lsb_helper<uint32_t >
171174{
172- static int32_t findLSB (NBL_CONST_REF_ARG (int32_t ) val)
175+ static int32_t findLSB (NBL_CONST_REF_ARG (uint32_t ) val)
173176 {
174177#ifdef __HLSL_VERSION
175178 return spirv::findILsb (val);
@@ -179,13 +182,44 @@ struct find_lsb_helper<int32_t>
179182 }
180183};
181184
185+ #define DEFINE_FIND_LSB_COMMON_SPECIALIZATION (INPUT_INTEGER_TYPE, INTEGER_TYPE)\
186+ template<>\
187+ struct find_lsb_helper<INPUT_INTEGER_TYPE>\
188+ {\
189+ static int32_t findLSB (NBL_CONST_REF_ARG (INPUT_INTEGER_TYPE) val)\
190+ {\
191+ return find_lsb_helper<INTEGER_TYPE>::findLSB (val);\
192+ }\
193+ };\
194+
195+ DEFINE_FIND_LSB_COMMON_SPECIALIZATION (int16_t, int32_t)
196+ DEFINE_FIND_LSB_COMMON_SPECIALIZATION (uint16_t, uint32_t)
197+ #ifndef __HLSL_VERSION
198+ DEFINE_FIND_LSB_COMMON_SPECIALIZATION (int8_t, int32_t)
199+ DEFINE_FIND_LSB_COMMON_SPECIALIZATION (uint8_t, uint32_t)
200+ #endif
201+
182202template<>
183- struct find_lsb_helper<uint32_t >
203+ struct find_lsb_helper<uint64_t >
184204{
185- static int32_t findLSB (NBL_CONST_REF_ARG (uint32_t ) val)
205+ static int32_t findLSB (NBL_CONST_REF_ARG (uint64_t ) val)
186206 {
187207#ifdef __HLSL_VERSION
188- return spirv::findILsb (val);
208+ const uint64_t lowBits = uint32_t (val);
209+ const uint64_t highBits = uint32_t (val >> 32 );
210+
211+ const int32_t lowLsb = findLSB (lowBits);
212+ if (lowLsb == -1 )
213+ {
214+ const uint64_t highBits = uint32_t (val >> 32 );
215+ const int32_t highLsb = findLSB (highBits);
216+ if (highBits == -1 )
217+ return -1 ;
218+ else
219+ return 32 + highLsb;
220+ }
221+
222+ return lowLsb;
189223#else
190224 return glm::findLSB (val);
191225#endif
0 commit comments