Skip to content

Commit 23292bd

Browse files
author
kevyuu
committed
Fix morton code constraint
1 parent 4c9635d commit 23292bd

File tree

1 file changed

+18
-12
lines changed

1 file changed

+18
-12
lines changed

include/nbl/builtin/hlsl/morton.hlsl

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -108,18 +108,21 @@ NBL_HLSL_MORTON_SPECIALIZE_LAST_CODING_MASKS
108108
template<uint16_t Dim, uint16_t Bits, typename encode_t NBL_PRIMARY_REQUIRES(Dimension<Dim> && Dim * Bits <= 64 && 8 * sizeof(encode_t) == mpl::max_v<uint64_t, mpl::round_up_to_pot_v<Dim * Bits>, uint64_t(16)>)
109109
struct Transcoder
110110
{
111-
template<typename decode_t = conditional_t<(Bits > 16), vector<uint32_t, Dim>, vector<uint16_t, Dim> >
112-
NBL_FUNC_REQUIRES(concepts::IntVector<decode_t> && 8 * sizeof(typename vector_traits<decode_t>::scalar_type) >= Bits)
111+
using decode_t = conditional_t < (Bits > 16), vector<uint32_t, Dim>, vector<uint16_t, Dim> >;
112+
113+
template<typename T
114+
NBL_FUNC_REQUIRES(concepts::same_as<T, decode_t> )
113115
/**
114116
* @brief Interleaves each coordinate with `Dim - 1` zeros inbetween each bit, and left-shifts each by their coordinate index
115117
*
116118
* @param [in] decodedValue Cartesian coordinates to interleave and shift
117119
*/
118-
NBL_CONSTEXPR_STATIC portable_vector_t<encode_t, Dim> interleaveShift(NBL_CONST_REF_ARG(decode_t) decodedValue)
120+
NBL_CONSTEXPR_STATIC portable_vector_t<encode_t, Dim> interleaveShift(NBL_CONST_REF_ARG(T) decodedValue)
119121
{
120122
left_shift_operator<portable_vector_t<encode_t, Dim> > leftShift;
121123
portable_vector_t<encode_t, Dim> interleaved = _static_cast<portable_vector_t<encode_t, Dim> >(decodedValue) & coding_mask_v<Dim, Bits, CodingStages, encode_t>;
122124

125+
// Read this to understand how interleaving and spreading bits works https://fgiesen.wordpress.com/2009/12/13/decoding-morton-codes/
123126
#define ENCODE_LOOP_ITERATION(I) NBL_IF_CONSTEXPR(Bits > (uint16_t(1) << I))\
124127
{\
125128
interleaved = interleaved | leftShift(interleaved, (uint16_t(1) << I) * (Dim - 1));\
@@ -137,15 +140,15 @@ struct Transcoder
137140
return leftShift(interleaved, truncate<vector<uint16_t, Dim> >(vector<uint16_t, 4>(0, 1, 2, 3)));
138141
}
139142

140-
template<typename decode_t = conditional_t<(Bits > 16), vector<uint32_t, Dim>, vector<uint16_t, Dim> > >
143+
template<typename T>
141144
/**
142145
* @brief Encodes a vector of cartesian coordinates as a Morton code
143146
*
144147
* @param [in] decodedValue Cartesian coordinates to encode
145148
*/
146-
NBL_CONSTEXPR_STATIC encode_t encode(NBL_CONST_REF_ARG(decode_t) decodedValue)
149+
NBL_CONSTEXPR_STATIC encode_t encode(NBL_CONST_REF_ARG(T) decodedValue)
147150
{
148-
const portable_vector_t<encode_t, Dim> interleaveShifted = interleaveShift<decode_t>(decodedValue);
151+
const portable_vector_t<encode_t, Dim> interleaveShifted = interleaveShift<T>(decodedValue);
149152

150153
array_get<portable_vector_t<encode_t, Dim>, encode_t> getter;
151154
encode_t encoded = getter(interleaveShifted, 0);
@@ -157,8 +160,6 @@ struct Transcoder
157160
return encoded;
158161
}
159162

160-
template<typename decode_t = conditional_t<(Bits > 16), vector<uint32_t, Dim>, vector<uint16_t, Dim> >
161-
NBL_FUNC_REQUIRES(concepts::IntVector<decode_t> && 8 * sizeof(typename vector_traits<decode_t>::scalar_type) >= Bits)
162163
/**
163164
* @brief Decodes a Morton code back to a vector of cartesian coordinates
164165
*
@@ -231,7 +232,8 @@ struct Equal<Signed, Bits, D, storage_t, false>
231232
NBL_CONSTEXPR_STATIC vector<bool, D> __call(NBL_CONST_REF_ARG(storage_t) value, NBL_CONST_REF_ARG(vector<I, D>) rhs)
232233
{
233234
using right_sign_t = conditional_t<Signed, make_signed_t<storage_t>, make_unsigned_t<storage_t> >;
234-
const portable_vector_t<right_sign_t, D> interleaved = _static_cast<portable_vector_t<right_sign_t, D> >(Transcoder<D, Bits, storage_t>::interleaveShift(rhs));
235+
using transcoder_t = Transcoder<D, Bits, storage_t>;
236+
const portable_vector_t<right_sign_t, D> interleaved = _static_cast<portable_vector_t<right_sign_t, D> >(transcoder_t::interleaveShift(_static_cast<typename transcoder_t::decode_t>(rhs)));
235237
return Equal<Signed, Bits, D, storage_t, true>::template __call<right_sign_t>(value, interleaved);
236238
}
237239
};
@@ -281,7 +283,8 @@ struct BaseComparison<Signed, Bits, D, storage_t, false, ComparisonOp>
281283
NBL_CONSTEXPR_STATIC vector<bool, D> __call(NBL_CONST_REF_ARG(storage_t) value, NBL_CONST_REF_ARG(vector<I, D>) rhs)
282284
{
283285
using right_sign_t = conditional_t<Signed, make_signed_t<storage_t>, make_unsigned_t<storage_t> >;
284-
const portable_vector_t<right_sign_t, D> interleaved = _static_cast<portable_vector_t<right_sign_t, D> >(Transcoder<D, Bits, storage_t>::interleaveShift(rhs));
286+
using transcoder_t = Transcoder<D, Bits, storage_t>;
287+
const portable_vector_t<right_sign_t, D> interleaved = _static_cast<portable_vector_t<right_sign_t, D> >(transcoder_t::interleaveShift(_static_cast<typename transcoder_t::decode_t>(rhs)));
285288
return BaseComparison<Signed, Bits, D, storage_t, true, ComparisonOp>::template __call<right_sign_t>(value, interleaved);
286289
}
287290
};
@@ -309,6 +312,8 @@ struct code
309312
using this_signed_t = code<true, Bits, D, _uint64_t>;
310313
NBL_CONSTEXPR_STATIC uint16_t TotalBitWidth = D * Bits;
311314
using storage_t = conditional_t<(TotalBitWidth > 16), conditional_t<(TotalBitWidth > 32), _uint64_t, uint32_t>, uint16_t>;
315+
316+
using transcoder_t = impl::Transcoder<D, Bits, storage_t>;
312317

313318
storage_t value;
314319

@@ -326,11 +331,12 @@ struct code
326331
* @param [in] cartesian Coordinates to encode. Signedness MUST match the signedness of this Morton code class
327332
*/
328333
template<typename I>
329-
NBL_CONSTEXPR_STATIC enable_if_t<is_integral_v<I> && is_scalar_v<I> && (is_signed_v<I> == Signed), this_t>
334+
NBL_CONSTEXPR_STATIC enable_if_t<is_integral_v<I> && is_scalar_v<I> && (is_signed_v<I> == Signed && sizeof(I) == sizeof(vector_traits<typename transcoder_t::decode_t>::scalar_type)), this_t>
330335
create(NBL_CONST_REF_ARG(vector<I, D>) cartesian)
331336
{
332337
this_t retVal;
333-
retVal.value = impl::Transcoder<D, Bits, storage_t>::encode(cartesian);
338+
using decode_t = typename transcoder_t::decode_t;
339+
retVal.value = transcoder_t::encode(_static_cast<decode_t>(cartesian));
334340
return retVal;
335341
}
336342

0 commit comments

Comments
 (0)