Skip to content

Commit b8e6d94

Browse files
committed
Created template findMSB and findLSB template specialization for every integer type
1 parent 172748a commit b8e6d94

File tree

6 files changed

+117
-58
lines changed

6 files changed

+117
-58
lines changed

include/nbl/asset/ICPUGraphicsPipeline.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ class ICPUGraphicsPipeline final : public ICPUPipeline<IGraphicsPipeline<ICPUPip
9393

9494
inline int8_t stageToIndex(const ICPUShader::E_SHADER_STAGE stage) const override
9595
{
96-
const auto stageIx = hlsl::findLSB(stage);
96+
const auto stageIx = hlsl::findLSB(static_cast<std::underlying_type_t<ICPUShader::E_SHADER_STAGE>>(stage));
9797
if (stageIx<0 || stageIx>=GRAPHICS_SHADER_STAGE_COUNT || hlsl::bitCount(stage)!=1)
9898
return -1;
9999
return stageIx;

include/nbl/asset/ICPURenderpassIndependentPipeline.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,14 +91,14 @@ class ICPURenderpassIndependentPipeline : public IRenderpassIndependentPipeline<
9191
inline IShader::SSpecInfo<ICPUShader> getSpecInfo(const ICPUShader::E_SHADER_STAGE stage)
9292
{
9393
assert(isMutable());
94-
const auto stageIx = hlsl::findLSB(stage);
94+
const auto stageIx = hlsl::findLSB(static_cast<std::underlying_type_t<ICPUShader::E_SHADER_STAGE>>(stage));
9595
if (stageIx<0 || stageIx>=GRAPHICS_SHADER_STAGE_COUNT || hlsl::bitCount(stage)!=1)
9696
return {};
9797
return m_infos[stageIx];
9898
}
9999
inline IShader::SSpecInfo<const ICPUShader> getSpecInfo(const ICPUShader::E_SHADER_STAGE stage) const
100100
{
101-
const auto stageIx = hlsl::findLSB(stage);
101+
const auto stageIx = hlsl::findLSB(static_cast<std::underlying_type_t<ICPUShader::E_SHADER_STAGE>>(stage));
102102
if (stageIx<0 || stageIx>=GRAPHICS_SHADER_STAGE_COUNT || hlsl::bitCount(stage)!=1)
103103
return {};
104104
return m_infos[stageIx];
@@ -110,7 +110,7 @@ class ICPURenderpassIndependentPipeline : public IRenderpassIndependentPipeline<
110110
if (specSize<0)
111111
return false;
112112
const auto stage = info.shader->getStage();
113-
const auto stageIx = hlsl::findLSB(stage);
113+
const auto stageIx = hlsl::findLSB(static_cast<std::underlying_type_t<ICPUShader::E_SHADER_STAGE>>(stage));
114114
if (stageIx<0 || stageIx>=GRAPHICS_SHADER_STAGE_COUNT || hlsl::bitCount(stage)!=1)
115115
return false;
116116
m_infos[stageIx] = info;

include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl

Lines changed: 85 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -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
5857
template<typename Integer>
5958
struct 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

8560
template<>
8661
struct 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+
111130
template<int N>
112131
struct 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
138156
template<typename Integer>
139157
struct 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

169172
template<>
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+
182202
template<>
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

include/nbl/core/util/bitflag.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#define _NBL_CORE_C_BITFLAG_H_INCLUDED_
66

77
#include "BuildConfigOptions.h"
8+
#include <nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl>
89

910
namespace nbl::core
1011
{
@@ -50,5 +51,29 @@ struct blake3_hasher::update_impl<core::bitflag<T>,Dummy>
5051

5152
template<typename T>
5253
concept Bitflag = std::is_same_v<bitflag<typename T::enum_t>, T>;
54+
55+
}
56+
57+
namespace nbl::hlsl::cpp_compat_intrinsics_impl
58+
{
59+
template<typename ENUM_TYPE>
60+
struct find_lsb_helper<core::bitflag<ENUM_TYPE>>
61+
{
62+
static int32_t findLSB(NBL_CONST_REF_ARG(core::bitflag<ENUM_TYPE>) val)
63+
{
64+
using underlying_t = typename core::bitflag<ENUM_TYPE>::UNDERLYING_TYPE;
65+
return find_lsb_helper<underlying_t>::findLSB(static_cast<underlying_t>(val.value));
66+
}
67+
};
68+
69+
template<typename ENUM_TYPE>
70+
struct find_msb_helper<core::bitflag<ENUM_TYPE>>
71+
{
72+
static int32_t findMSB(NBL_CONST_REF_ARG(core::bitflag<ENUM_TYPE>) val)
73+
{
74+
using underlying_t = typename core::bitflag<ENUM_TYPE>::UNDERLYING_TYPE;
75+
return find_msb_helper<underlying_t>::findMSB(static_cast<underlying_t>(val.value));
76+
}
77+
};
5378
}
5479
#endif

src/nbl/video/CVulkanGraphicsPipeline.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ class CVulkanGraphicsPipeline final : public IGPUGraphicsPipeline
1919
for (const auto& info : params.shaders)
2020
if (info.shader)
2121
{
22-
const auto stageIx = hlsl::findLSB(info.shader->getStage());
22+
const auto stageIx = hlsl::findLSB(static_cast<std::underlying_type_t<asset::IShader::E_SHADER_STAGE>>(info.shader->getStage()));
2323
m_shaders[stageIx] = core::smart_refctd_ptr<const CVulkanShader>(static_cast<const CVulkanShader*>(info.shader));
2424
}
2525
}

src/nbl/video/utilities/CAssetConverter.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1509,7 +1509,7 @@ class GetDependantVisit<ICPUComputePipeline> : public GetDependantVisitBase<ICPU
15091509
inline auto& getSpecInfo(const IShader::E_SHADER_STAGE stage)
15101510
{
15111511
assert(hlsl::bitCount(stage)==1);
1512-
return specInfo[hlsl::findLSB(stage)];
1512+
return specInfo[hlsl::findLSB(static_cast<std::underlying_type_t<IShader::E_SHADER_STAGE>>(stage))];
15131513
}
15141514

15151515
// ok to do non owning since some cache owns anyway
@@ -1557,7 +1557,7 @@ class GetDependantVisit<ICPUGraphicsPipeline> : public GetDependantVisitBase<ICP
15571557
inline auto& getSpecInfo(const IShader::E_SHADER_STAGE stage)
15581558
{
15591559
assert(hlsl::bitCount(stage)==1);
1560-
return specInfo[hlsl::findLSB(stage)];
1560+
return specInfo[hlsl::findLSB(static_cast<std::underlying_type_t<IShader::E_SHADER_STAGE>>(stage))];
15611561
}
15621562

15631563
// ok to do non owning since some cache owns anyway

0 commit comments

Comments
 (0)