Skip to content

Commit 664c129

Browse files
author
devsh
committed
fix is_spirv_type
1 parent 60df17b commit 664c129

File tree

4 files changed

+87
-41
lines changed

4 files changed

+87
-41
lines changed

include/nbl/builtin/hlsl/bda/__ptr.hlsl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,12 @@ struct __ptr
6565
__ptr operator+(int64_t i)
6666
{
6767
i *= sizeof(T);
68-
return __ptr::create(spirv::bitcast<uint64_t>(addr) + i);
68+
return __ptr::create(spirv::bitcast<uint64_t>(addr)+i);
6969
}
7070
__ptr operator-(int64_t i)
7171
{
7272
i *= sizeof(T);
73-
return __ptr::create(spirv::bitcast<uint64_t>(addr) - i);
73+
return __ptr::create(spirv::bitcast<uint64_t>(addr)-i);
7474
}
7575
};
7676

include/nbl/builtin/hlsl/glsl_compat/core.hlsl

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ T atomicAdd(NBL_REF_ARG(T) ptr, T value)
5252
return spirv::atomicIAdd<T>(ptr, spv::ScopeDevice, spv::MemorySemanticsMaskNone, value);
5353
}
5454
template<typename T, typename Ptr_T> // DXC Workaround
55-
enable_if_t<is_spirv_type_v<Ptr_T>, T> atomicAdd(Ptr_T ptr, T value)
55+
enable_if_t<spirv::is_pointer_v<Ptr_T>, T> atomicAdd(Ptr_T ptr, T value)
5656
{
5757
return spirv::atomicIAdd<T, Ptr_T>(ptr, spv::ScopeDevice, spv::MemorySemanticsMaskNone, value);
5858
}
@@ -62,7 +62,7 @@ T atomicSub(NBL_REF_ARG(T) ptr, T value)
6262
return spirv::atomicISub<T>(ptr, spv::ScopeDevice, spv::MemorySemanticsMaskNone, value);
6363
}
6464
template<typename T, typename Ptr_T> // DXC Workaround
65-
enable_if_t<is_spirv_type_v<Ptr_T>, T> atomicSub(Ptr_T ptr, T value)
65+
enable_if_t<spirv::is_pointer_v<Ptr_T>, T> atomicSub(Ptr_T ptr, T value)
6666
{
6767
return spirv::atomicISub<T, Ptr_T>(ptr, spv::ScopeDevice, spv::MemorySemanticsMaskNone, value);
6868
}
@@ -72,7 +72,7 @@ T atomicAnd(NBL_REF_ARG(T) ptr, T value)
7272
return spirv::atomicAnd<T>(ptr, spv::ScopeDevice, spv::MemorySemanticsMaskNone, value);
7373
}
7474
template<typename T, typename Ptr_T> // DXC Workaround
75-
enable_if_t<is_spirv_type_v<Ptr_T>, T> atomicAnd(Ptr_T ptr, T value)
75+
enable_if_t<spirv::is_pointer_v<Ptr_T>, T> atomicAnd(Ptr_T ptr, T value)
7676
{
7777
return spirv::atomicAnd<T, Ptr_T>(ptr, spv::ScopeDevice, spv::MemorySemanticsMaskNone, value);
7878
}
@@ -82,7 +82,7 @@ T atomicOr(NBL_REF_ARG(T) ptr, T value)
8282
return spirv::atomicOr<T>(ptr, spv::ScopeDevice, spv::MemorySemanticsMaskNone, value);
8383
}
8484
template<typename T, typename Ptr_T> // DXC Workaround
85-
enable_if_t<is_spirv_type_v<Ptr_T>, T> atomicOr(Ptr_T ptr, T value)
85+
enable_if_t<spirv::is_pointer_v<Ptr_T>, T> atomicOr(Ptr_T ptr, T value)
8686
{
8787
return spirv::atomicOr<T, Ptr_T>(ptr, spv::ScopeDevice, spv::MemorySemanticsMaskNone, value);
8888
}
@@ -92,7 +92,7 @@ T atomicXor(NBL_REF_ARG(T) ptr, T value)
9292
return spirv::atomicXor<T>(ptr, spv::ScopeDevice, spv::MemorySemanticsMaskNone, value);
9393
}
9494
template<typename T, typename Ptr_T> // DXC Workaround
95-
enable_if_t<is_spirv_type_v<Ptr_T>, T> atomicXor(Ptr_T ptr, T value)
95+
enable_if_t<spirv::is_pointer_v<Ptr_T>, T> atomicXor(Ptr_T ptr, T value)
9696
{
9797
return spirv::atomicXor<T, Ptr_T>(ptr, spv::ScopeDevice, spv::MemorySemanticsMaskNone, value);
9898
}
@@ -112,7 +112,7 @@ T atomicExchange(NBL_REF_ARG(T) ptr, T value)
112112
return spirv::atomicExchange<T>(ptr, spv::ScopeDevice, spv::MemorySemanticsMaskNone, value);
113113
}
114114
template<typename T, typename Ptr_T> // DXC Workaround
115-
enable_if_t<is_spirv_type_v<Ptr_T>, T> atomicExchange(Ptr_T ptr, T value)
115+
enable_if_t<spirv::is_pointer_v<Ptr_T>, T> atomicExchange(Ptr_T ptr, T value)
116116
{
117117
return spirv::atomicExchange<T, Ptr_T>(ptr, spv::ScopeDevice, spv::MemorySemanticsMaskNone, value);
118118
}
@@ -122,7 +122,7 @@ T atomicCompSwap(NBL_REF_ARG(T) ptr, T comparator, T value)
122122
return spirv::atomicCompareExchange<T>(ptr, spv::ScopeDevice, spv::MemorySemanticsMaskNone, spv::MemorySemanticsMaskNone, value, comparator);
123123
}
124124
template<typename T, typename Ptr_T> // DXC Workaround
125-
enable_if_t<is_spirv_type_v<Ptr_T>, T> atomicCompSwap(Ptr_T ptr, T comparator, T value)
125+
enable_if_t<spirv::is_pointer_v<Ptr_T>, T> atomicCompSwap(Ptr_T ptr, T comparator, T value)
126126
{
127127
return spirv::atomicCompareExchange<T, Ptr_T>(ptr, spv::ScopeDevice, spv::MemorySemanticsMaskNone, spv::MemorySemanticsMaskNone, value, comparator);
128128
}

include/nbl/builtin/hlsl/spirv_intrinsics/core.hlsl

Lines changed: 35 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,23 @@ template<uint32_t StorageClass, typename T>
9292
using pointer_t = vk::SpirvOpaqueType<spv::OpTypePointer,vk::Literal<vk::integral_constant<uint32_t,StorageClass> >,T>;
9393

9494
template<typename T>
95-
using bda_pointer_t __NBL_CAPABILITY_PhysicalStorageBufferAddresses = vk::SpirvType<spv::OpTypePointer, sizeof(uint64_t),/*alignof(uint64_t)*/8, vk::Literal<vk::integral_constant<uint32_t, spv::StorageClassPhysicalStorageBuffer> >, T>;
95+
struct is_pointer : false_type {};
96+
template<typename I, I StorageClass, typename TT>
97+
struct is_pointer<vk::SpirvOpaqueType<spv::OpTypePointer,vk::Literal<vk::integral_constant<I,StorageClass> >,TT> > : is_integral<I> {};
98+
template<uint32_t Size, uint32_t Alignment, typename I, I StorageClass, typename TT>
99+
struct is_pointer<vk::SpirvType<spv::OpTypePointer,Size,Alignment,vk::Literal<vk::integral_constant<I,StorageClass> >,TT> > : is_integral<I> {};
100+
template<class T>
101+
NBL_CONSTEXPR_STATIC_INLINE bool is_pointer_v = is_pointer<T>::value;
102+
103+
template<typename T>
104+
using bda_pointer_t __NBL_CAPABILITY_PhysicalStorageBufferAddresses = vk::SpirvType<spv::OpTypePointer, sizeof(uint64_t),alignment_of_v<uint64_t>, vk::Literal<vk::integral_constant<uint32_t, spv::StorageClassPhysicalStorageBuffer> >, T>;
105+
106+
template<typename T>
107+
struct is_bda_pointer : false_type {};
108+
template<typename I, typename TT>
109+
struct is_pointer<vk::SpirvType<spv::OpTypePointer,sizeof(uint64_t),alignment_of_v<uint64_t>,vk::Literal<vk::integral_constant<I, spv::StorageClassPhysicalStorageBuffer> >, TT> > : is_integral<I> {};
110+
template<class T>
111+
NBL_CONSTEXPR_STATIC_INLINE bool is_bda_pointer_v = is_bda_pointer<T>::value;
96112

97113

98114
//! General Operations
@@ -116,7 +132,7 @@ template<typename T, typename U>
116132
enable_if_t<!is_same_v<T,U>,T> copyLogical([[vk::ext_reference]] U v);
117133
template<typename T, typename Ptr_U>
118134
[[vk::ext_instruction(spv::OpCopyLogical)]]
119-
enable_if_t<is_spirv_type_v<Ptr_U>/* && !is_same_v<T,U>*/,T> copyLogical(Ptr_U v);
135+
enable_if_t<is_pointer_v<Ptr_U>/* && !is_same_v<T,U>*/,T> copyLogical(Ptr_U v);
120136

121137
// Here's the thing with atomics, it's not only the data type that dictates whether you can do an atomic or not.
122138
// It's the storage class that has the most effect (shared vs storage vs image) and we can't check that easily
@@ -126,7 +142,7 @@ enable_if_t<is_same_v<T,uint32_t> || is_same_v<T,int32_t>, T> atomicIAdd([[vk::e
126142

127143
template<typename T, typename Ptr_T> // DXC Workaround
128144
[[vk::ext_instruction(spv::OpAtomicIAdd)]]
129-
enable_if_t<is_spirv_type_v<Ptr_T> && (is_same_v<T,uint32_t> || is_same_v<T,int32_t>), T> atomicIAdd(Ptr_T ptr, uint32_t memoryScope, uint32_t memorySemantics, T value);
145+
enable_if_t<is_pointer_v<Ptr_T> && (is_same_v<T,uint32_t> || is_same_v<T,int32_t>), T> atomicIAdd(Ptr_T ptr, uint32_t memoryScope, uint32_t memorySemantics, T value);
130146

131147
template<typename T> // integers operate on 2s complement so same op for signed and unsigned
132148
[[vk::ext_capability(spv::CapabilityInt64Atomics)]]
@@ -136,15 +152,15 @@ enable_if_t<is_same_v<T,uint64_t> || is_same_v<T,int64_t>, T> atomicIAdd([[vk::e
136152
template<typename T, typename Ptr_T> // DXC Workaround
137153
[[vk::ext_capability(spv::CapabilityInt64Atomics)]]
138154
[[vk::ext_instruction(spv::OpAtomicIAdd)]]
139-
enable_if_t<is_spirv_type_v<Ptr_T> && (is_same_v<T,uint64_t> || is_same_v<T,int64_t>), T> atomicIAdd(Ptr_T ptr, uint32_t memoryScope, uint32_t memorySemantics, T value);
155+
enable_if_t<is_pointer_v<Ptr_T> && (is_same_v<T,uint64_t> || is_same_v<T,int64_t>), T> atomicIAdd(Ptr_T ptr, uint32_t memoryScope, uint32_t memorySemantics, T value);
140156

141157
template<typename T> // integers operate on 2s complement so same op for signed and unsigned
142158
[[vk::ext_instruction(spv::OpAtomicISub)]]
143159
enable_if_t<is_same_v<T,uint32_t> || is_same_v<T,int32_t>, T> atomicISub([[vk::ext_reference]] T ptr, uint32_t memoryScope, uint32_t memorySemantics, T value);
144160

145161
template<typename T, typename Ptr_T> // DXC Workaround
146162
[[vk::ext_instruction(spv::OpAtomicISub)]]
147-
enable_if_t<is_spirv_type_v<Ptr_T> && (is_same_v<T,uint32_t> || is_same_v<T,int32_t>), T> atomicISub(Ptr_T ptr, uint32_t memoryScope, uint32_t memorySemantics, T value);
163+
enable_if_t<is_pointer_v<Ptr_T> && (is_same_v<T,uint32_t> || is_same_v<T,int32_t>), T> atomicISub(Ptr_T ptr, uint32_t memoryScope, uint32_t memorySemantics, T value);
148164

149165
template<typename T> // integers operate on 2s complement so same op for signed and unsigned
150166
[[vk::ext_capability(spv::CapabilityInt64Atomics)]]
@@ -154,79 +170,79 @@ enable_if_t<is_same_v<T,uint64_t> || is_same_v<T,int64_t>, T> atomicISub([[vk::e
154170
template<typename T, typename Ptr_T> // DXC Workaround
155171
[[vk::ext_capability(spv::CapabilityInt64Atomics)]]
156172
[[vk::ext_instruction(spv::OpAtomicISub)]]
157-
enable_if_t<is_spirv_type_v<Ptr_T> && (is_same_v<T,uint64_t> || is_same_v<T,int64_t>), T> atomicISub(Ptr_T ptr, uint32_t memoryScope, uint32_t memorySemantics, T value);
173+
enable_if_t<is_pointer_v<Ptr_T> && (is_same_v<T,uint64_t> || is_same_v<T,int64_t>), T> atomicISub(Ptr_T ptr, uint32_t memoryScope, uint32_t memorySemantics, T value);
158174

159175
template<typename T>
160176
[[vk::ext_instruction(spv::OpAtomicAnd)]]
161177
enable_if_t<is_same_v<T,uint32_t> || is_same_v<T,int32_t>, T> atomicAnd([[vk::ext_reference]] T ptr, uint32_t memoryScope, uint32_t memorySemantics, T value);
162178

163179
template<typename T, typename Ptr_T> // DXC Workaround
164180
[[vk::ext_instruction(spv::OpAtomicAnd)]]
165-
enable_if_t<is_spirv_type_v<Ptr_T> && (is_same_v<T,uint32_t> || is_same_v<T,int32_t>), T> atomicAnd(Ptr_T ptr, uint32_t memoryScope, uint32_t memorySemantics, T value);
181+
enable_if_t<is_pointer_v<Ptr_T> && (is_same_v<T,uint32_t> || is_same_v<T,int32_t>), T> atomicAnd(Ptr_T ptr, uint32_t memoryScope, uint32_t memorySemantics, T value);
166182

167183
template<typename T>
168184
[[vk::ext_instruction(spv::OpAtomicOr)]]
169185
enable_if_t<is_same_v<T,uint32_t> || is_same_v<T,int32_t>, T> atomicOr([[vk::ext_reference]] T ptr, uint32_t memoryScope, uint32_t memorySemantics, T value);
170186

171187
template<typename T, typename Ptr_T> // DXC Workaround
172188
[[vk::ext_instruction(spv::OpAtomicOr)]]
173-
enable_if_t<is_spirv_type_v<Ptr_T> && (is_same_v<T,uint32_t> || is_same_v<T,int32_t>), T> atomicOr(Ptr_T ptr, uint32_t memoryScope, uint32_t memorySemantics, T value);
189+
enable_if_t<is_pointer_v<Ptr_T> && (is_same_v<T,uint32_t> || is_same_v<T,int32_t>), T> atomicOr(Ptr_T ptr, uint32_t memoryScope, uint32_t memorySemantics, T value);
174190

175191
template<typename T>
176192
[[vk::ext_instruction(spv::OpAtomicXor)]]
177193
enable_if_t<is_same_v<T,uint32_t> || is_same_v<T,int32_t>, T> atomicXor([[vk::ext_reference]] T ptr, uint32_t memoryScope, uint32_t memorySemantics, T value);
178194

179195
template<typename T, typename Ptr_T> // DXC Workaround
180196
[[vk::ext_instruction(spv::OpAtomicXor)]]
181-
enable_if_t<is_spirv_type_v<Ptr_T> && (is_same_v<T,uint32_t> || is_same_v<T,int32_t>), T> atomicXor(Ptr_T ptr, uint32_t memoryScope, uint32_t memorySemantics, T value);
197+
enable_if_t<is_pointer_v<Ptr_T> && (is_same_v<T,uint32_t> || is_same_v<T,int32_t>), T> atomicXor(Ptr_T ptr, uint32_t memoryScope, uint32_t memorySemantics, T value);
182198

183199
template<typename Signed>
184200
[[vk::ext_instruction( spv::OpAtomicSMin )]]
185201
enable_if_t<is_same_v<Signed,int32_t>, Signed> atomicSMin([[vk::ext_reference]] int32_t ptr, uint32_t memoryScope, uint32_t memorySemantics, Signed value);
186202

187203
template<typename Signed, typename Ptr_T> // DXC Workaround
188204
[[vk::ext_instruction(spv::OpAtomicSMin)]]
189-
enable_if_t<is_spirv_type_v<Ptr_T> && is_same_v<Signed,int32_t>, Signed> atomicSMin(Ptr_T ptr, uint32_t memoryScope, uint32_t memorySemantics, Signed value);
205+
enable_if_t<is_pointer_v<Ptr_T> && is_same_v<Signed,int32_t>, Signed> atomicSMin(Ptr_T ptr, uint32_t memoryScope, uint32_t memorySemantics, Signed value);
190206

191207
template<typename Unsigned>
192208
[[vk::ext_instruction( spv::OpAtomicUMin )]]
193209
enable_if_t<is_same_v<Unsigned,uint32_t>, Unsigned> atomicUMin([[vk::ext_reference]] Unsigned ptr, uint32_t memoryScope, uint32_t memorySemantics, Unsigned value);
194210

195211
template<typename Unsigned, typename Ptr_T> // DXC Workaround
196212
[[vk::ext_instruction(spv::OpAtomicUMin)]]
197-
enable_if_t<is_spirv_type_v<Ptr_T> && is_same_v<Unsigned,uint32_t>, Unsigned> atomicUMin(Ptr_T ptr, uint32_t memoryScope, uint32_t memorySemantics, Unsigned value);
213+
enable_if_t<is_pointer_v<Ptr_T> && is_same_v<Unsigned,uint32_t>, Unsigned> atomicUMin(Ptr_T ptr, uint32_t memoryScope, uint32_t memorySemantics, Unsigned value);
198214

199215
template<typename Signed>
200216
[[vk::ext_instruction( spv::OpAtomicSMax )]]
201217
enable_if_t<is_same_v<Signed,int32_t>, Signed> atomicSMax([[vk::ext_reference]] Signed ptr, uint32_t memoryScope, uint32_t memorySemantics, Signed value);
202218

203219
template<typename Signed, typename Ptr_T> // DXC Workaround
204220
[[vk::ext_instruction(spv::OpAtomicSMax)]]
205-
enable_if_t<is_spirv_type_v<Ptr_T> && is_same_v<Signed,int32_t>, Signed> atomicSMax(Ptr_T ptr, uint32_t memoryScope, uint32_t memorySemantics, Signed value);
221+
enable_if_t<is_pointer_v<Ptr_T> && is_same_v<Signed,int32_t>, Signed> atomicSMax(Ptr_T ptr, uint32_t memoryScope, uint32_t memorySemantics, Signed value);
206222

207223
template<typename Unsigned>
208224
[[vk::ext_instruction( spv::OpAtomicUMax )]]
209225
enable_if_t<is_same_v<Unsigned,uint32_t>, Unsigned> atomicUMax([[vk::ext_reference]] uint32_t ptr, uint32_t memoryScope, uint32_t memorySemantics, Unsigned value);
210226

211227
template<typename Unsigned, typename Ptr_T> // DXC Workaround
212228
[[vk::ext_instruction(spv::OpAtomicUMax)]]
213-
enable_if_t<is_spirv_type_v<Ptr_T> && is_same_v<Unsigned,uint32_t>, Unsigned> atomicUMax(Ptr_T ptr, uint32_t memoryScope, uint32_t memorySemantics, Unsigned value);
229+
enable_if_t<is_pointer_v<Ptr_T> && is_same_v<Unsigned,uint32_t>, Unsigned> atomicUMax(Ptr_T ptr, uint32_t memoryScope, uint32_t memorySemantics, Unsigned value);
214230

215231
template<typename T>
216232
[[vk::ext_instruction(spv::OpAtomicExchange)]]
217233
T atomicExchange([[vk::ext_reference]] T ptr, uint32_t memoryScope, uint32_t memorySemantics, T value);
218234

219235
template<typename T, typename Ptr_T> // DXC Workaround
220236
[[vk::ext_instruction(spv::OpAtomicExchange)]]
221-
enable_if_t<is_spirv_type_v<Ptr_T>, T> atomicExchange(Ptr_T ptr, uint32_t memoryScope, uint32_t memorySemantics, T value);
237+
enable_if_t<is_pointer_v<Ptr_T>, T> atomicExchange(Ptr_T ptr, uint32_t memoryScope, uint32_t memorySemantics, T value);
222238

223239
template<typename T>
224240
[[vk::ext_instruction(spv::OpAtomicCompareExchange)]]
225241
T atomicCompareExchange([[vk::ext_reference]] T ptr, uint32_t memoryScope, uint32_t memSemanticsEqual, uint32_t memSemanticsUnequal, T value, T comparator);
226242

227243
template<typename T, typename Ptr_T> // DXC Workaround
228244
[[vk::ext_instruction(spv::OpAtomicCompareExchange)]]
229-
enable_if_t<is_spirv_type_v<Ptr_T>, T> atomicCompareExchange(Ptr_T ptr, uint32_t memoryScope, uint32_t memSemanticsEqual, uint32_t memSemanticsUnequal, T value, T comparator);
245+
enable_if_t<is_pointer_v<Ptr_T>, T> atomicCompareExchange(Ptr_T ptr, uint32_t memoryScope, uint32_t memSemanticsEqual, uint32_t memSemanticsUnequal, T value, T comparator);
230246

231247

232248
template<typename T, uint32_t alignment>
@@ -236,7 +252,7 @@ T load(bda_pointer_t<T> pointer, [[vk::ext_literal]] uint32_t __aligned = /*Alig
236252

237253
template<typename T, typename P>
238254
[[vk::ext_instruction(spv::OpLoad)]]
239-
enable_if_t<is_spirv_type_v<P>,T> load(P pointer);
255+
enable_if_t<is_pointer_v<P>,T> load(P pointer);
240256

241257
template<typename T, uint32_t alignment>
242258
__NBL_CAPABILITY_PhysicalStorageBufferAddresses
@@ -245,7 +261,7 @@ void store(bda_pointer_t<T> pointer, T obj, [[vk::ext_literal]] uint32_t __align
245261

246262
template<typename T, typename P>
247263
[[vk::ext_instruction(spv::OpStore)]]
248-
enable_if_t<is_spirv_type_v<P>,void> store(P pointer, T obj);
264+
enable_if_t<is_pointer_v<P>,void> store(P pointer, T obj);
249265

250266
// Memory Semantics link here: https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#Memory_Semantics_-id-
251267

@@ -261,19 +277,10 @@ void memoryBarrier(uint32_t memoryScope, uint32_t memorySemantics);
261277
// Add specializations if you need to emit a `ext_capability` (this means that the instruction needs to forward through an `impl::` struct and so on)
262278
// TODO: better constraints, one should only be able to cast fundamental types, etc. https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#OpBitcast
263279
#if 0
280+
// mutitple overloads should be possible
264281
template<typename T, typename U>
265282
[[vk::ext_instruction(spv::OpBitcast)]]
266-
enable_if_t<is_spirv_type_v<T> && is_spirv_type_v<U>, T> bitcast(U);
267-
268-
template<typename U, typename T>
269-
__NBL_CAPABILITY_PhysicalStorageBufferAddresses
270-
[[vk::ext_instruction(spv::OpBitcast)]]
271-
enable_if_t<is_same_v<U,uint64_t2>||is_same_v<U,uint32_t2>,U> bitcast(bda_pointer_t<T>);
272-
273-
template<typename T, typename U>
274-
__NBL_CAPABILITY_PhysicalStorageBufferAddresses
275-
[[vk::ext_instruction(spv::OpBitcast)]]
276-
enable_if_t<is_same_v<U,uint64_t2>||is_same_v<U,uint32_t2>,bda_pointer_t<T> > bitcast(U);
283+
enable_if_t<TODO: CONDITIONS, T> bitcast(U);
277284
#endif
278285
template<class T, class U>
279286
[[vk::ext_instruction(spv::OpBitcast)]]

include/nbl/builtin/hlsl/type_traits.hlsl

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -294,14 +294,53 @@ struct is_signed : bool_constant<
294294

295295
}
296296

297-
// TODO: struct & trait is named wrong
297+
298+
//! For inline SPIR-V
299+
template<typename T>
300+
struct is_vk_Literal : false_type {};
301+
template<typename IC>
302+
struct is_vk_Literal<vk::Literal<IC> > : true_type
303+
{
304+
using type = IC;
305+
};
306+
template<typename T>
307+
NBL_CONSTEXPR_STATIC_INLINE bool is_vk_Literal_v = is_vk_Literal<T>::value;
308+
309+
// DXC doesn't support variadics, matches need to be declared in reverse, most args to least (in case templates have defaults0
310+
#include <boost/preprocessor/repetition/repeat.hpp>
311+
#define NBL_IMPL_CAT(z,n,text) ,text ## n
312+
313+
template<typename T>
314+
struct is_spirv_opaque_type : false_type {};
315+
#define DECLARE_VARIADIC_MATCH(N) template<uint32_t OpType BOOST_PP_REPEAT(N,NBL_IMPL_CAT,typename T)> \
316+
struct is_spirv_opaque_type<vk::SpirvOpaqueType<OpType BOOST_PP_REPEAT(N,NBL_IMPL_CAT,T)> > : true_type {}
317+
DECLARE_VARIADIC_MATCH(3);
318+
DECLARE_VARIADIC_MATCH(2);
319+
DECLARE_VARIADIC_MATCH(1);
320+
DECLARE_VARIADIC_MATCH(0);
321+
#undef DECLARE_VARIADIC_MATCH
298322
template<class T>
299-
struct is_spirv_type : false_type {};
300-
template<class T, class Storage>
301-
struct is_spirv_type< vk::SpirvOpaqueType</*spv::OpTypePointer*/ 32, Storage, T> > : true_type {};
323+
NBL_CONSTEXPR_STATIC_INLINE bool is_spirv_opaque_type_v = is_spirv_opaque_type<T>::value;
324+
325+
template<typename T>
326+
struct is_spirv_storable_type : false_type {};
327+
#define DECLARE_VARIADIC_MATCH(N) template<uint32_t OpType, uint32_t Size, uint32_t Alignment BOOST_PP_REPEAT(N,NBL_IMPL_CAT,typename T)> \
328+
struct is_spirv_storable_type<vk::SpirvType<OpType,Size,Alignment BOOST_PP_REPEAT(N,NBL_IMPL_CAT,T)> > : true_type {};
329+
DECLARE_VARIADIC_MATCH(3)
330+
DECLARE_VARIADIC_MATCH(2)
331+
DECLARE_VARIADIC_MATCH(1)
332+
DECLARE_VARIADIC_MATCH(0)
333+
#undef DECLARE_VARIADIC_MATCH
334+
template<class T>
335+
NBL_CONSTEXPR_STATIC_INLINE bool is_spirv_storable_type_v = is_spirv_storable_type<T>::value;
336+
337+
#undef NBL_IMPL_CAT
338+
template<typename T>
339+
struct is_spirv_type : bool_constant<is_spirv_opaque_type_v<T>||is_spirv_storable_type_v<T> > {};
302340
template<class T>
303341
NBL_CONSTEXPR_STATIC_INLINE bool is_spirv_type_v = is_spirv_type<T>::value;
304342

343+
305344
template<class T>
306345
struct is_unsigned : impl::base_type_forwarder<impl::is_unsigned, typename remove_cv<T>::type> {};
307346

0 commit comments

Comments
 (0)