Thanks for using Compiler Explorer
Sponsors
Jakt
C++
Ada
Algol68
Analysis
Android Java
Android Kotlin
Assembly
C
C3
Carbon
C with Coccinelle
C++ with Coccinelle
C++ (Circle)
CIRCT
Clean
Clojure
CMake
CMakeScript
COBOL
C++ for OpenCL
MLIR
Cppx
Cppx-Blue
Cppx-Gold
Cpp2-cppfront
Crystal
C#
CUDA C++
D
Dart
Elixir
Erlang
Fortran
F#
GLSL
Go
Haskell
HLSL
Hook
Hylo
IL
ispc
Java
Julia
Kotlin
LLVM IR
LLVM MIR
Modula-2
Mojo
Nim
Numba
Nix
Objective-C
Objective-C++
OCaml
Odin
OpenCL C
Pascal
Pony
PTX
Python
Racket
Raku
Ruby
Rust
Sail
Snowball
Scala
Slang
Solidity
Spice
SPIR-V
Swift
LLVM TableGen
Toit
Triton
TypeScript Native
V
Vala
Visual Basic
Vyper
WASM
Yul (Solidity IR)
Zig
Javascript
GIMPLE
Ygen
sway
hlsl source #1
Output
Compile to binary object
Link to binary
Execute the code
Intel asm syntax
Demangle identifiers
Verbose demangling
Filters
Unused labels
Library functions
Directives
Comments
Horizontal whitespace
Debug intrinsics
Compiler
AMD RGA 2.10
AMD RGA 2.11
AMD RGA 2.12
AMD RGA 2.13
AMD RGA 2.9.1
Clang (assertions trunk)
Clang (trunk)
DXC (trunk)
DXC 1.6.2112
DXC 1.7.2207
DXC 1.7.2212
DXC 1.7.2308
DXC 1.8.2306-preview
DXC 1.8.2403
DXC 1.8.2403.1
DXC 1.8.2403.2
DXC 1.8.2405
DXC 1.8.2407
DXC 1.8.2502
DXC 1.8.2505
DXC 1.8.2505.1
RGA 2.6.1 (DXC 1.6.2112)
RGA 2.6.1 (DXC 1.7.2207)
RGA 2.6.2 (DXC 1.6.2112)
RGA 2.6.2 (DXC 1.7.2207)
RGA 2.6.2 (DXC trunk)
RGA 2.9.0 (DXC trunk)
Options
Source code
#line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/macros.h" // Copyright (C) 2022 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 8 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/macros.h" // TODO: DXC doesn't get this, we need our own // TODO: switch between enabled and disabled depending on Nabla build config #line 43 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/macros.h" // basics #line 49 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/macros.h" // variadics // #line 55 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/macros.h" // TODO: Use BOOST_PP! #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts/impl/base.hlsl" // Copyright (C) 2023-2024 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 7 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts/impl/base.hlsl" namespace nbl { namespace hlsl { namespace concepts { //! Now diverge #line 25 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts/impl/base.hlsl" // to define a concept using `concept Name = SomeContexprBoolCondition<T>;` // to put right before the closing `>` of the primary template definition, otherwise `NBL_PARTIAL_REQUIRES` wont work on specializations #line 32 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts/impl/base.hlsl" } } } #line 54 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/cpp_compat/basic.h" namespace nbl { namespace hlsl { #line 72 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/cpp_compat/basic.h" } } #line 80 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/cpp_compat/basic.h" namespace nbl { namespace hlsl { namespace impl { template<typename To, typename From, typename Enabled = void ,typename __requires=void > struct static_cast_helper { static inline To cast(const in From u) { #line 94 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/cpp_compat/basic.h" return To(u); } }; } template<typename To, typename From> inline To _static_cast(const in From v) { return impl::static_cast_helper<To, From>::cast(v); } } } #line 5 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/cpp_compat.hlsl" // it includes vector and matrix #line 4 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/cpp_compat/vector.hlsl" // stuff for C++ #line 48 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/cpp_compat/vector.hlsl" // general typedefs for both langs namespace nbl { namespace hlsl { typedef half float16_t; typedef float float32_t; typedef double float64_t; #line 63 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/cpp_compat/vector.hlsl" // ideally we should have sized bools, but no idea what they'd be typedef vector<bool,4> bool4; typedef vector<bool,3> bool3; typedef vector<bool,2> bool2; typedef vector<bool,1> bool1; typedef vector<int16_t,4> int16_t4; typedef vector<int16_t,3> int16_t3; typedef vector<int16_t,2> int16_t2; typedef vector<int16_t,1> int16_t1; typedef vector<int32_t,4> int32_t4; typedef vector<int32_t,3> int32_t3; typedef vector<int32_t,2> int32_t2; typedef vector<int32_t,1> int32_t1; typedef vector<int64_t,4> int64_t4; typedef vector<int64_t,3> int64_t3; typedef vector<int64_t,2> int64_t2; typedef vector<int64_t,1> int64_t1; typedef vector<uint16_t,4> uint16_t4; typedef vector<uint16_t,3> uint16_t3; typedef vector<uint16_t,2> uint16_t2; typedef vector<uint16_t,1> uint16_t1; typedef vector<uint32_t,4> uint32_t4; typedef vector<uint32_t,3> uint32_t3; typedef vector<uint32_t,2> uint32_t2; typedef vector<uint32_t,1> uint32_t1; typedef vector<uint64_t,4> uint64_t4; typedef vector<uint64_t,3> uint64_t3; typedef vector<uint64_t,2> uint64_t2; typedef vector<uint64_t,1> uint64_t1; typedef vector<float16_t,4> float16_t4; typedef vector<float16_t,3> float16_t3; typedef vector<float16_t,2> float16_t2; typedef vector<float16_t,1> float16_t1; typedef vector<float32_t,4> float32_t4; typedef vector<float32_t,3> float32_t3; typedef vector<float32_t,2> float32_t2; typedef vector<float32_t,1> float32_t1; typedef vector<float64_t,4> float64_t4; typedef vector<float64_t,3> float64_t3; typedef vector<float64_t,2> float64_t2; typedef vector<float64_t,1> float64_t1; } #line 94 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/cpp_compat/vector.hlsl" } #line 6 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/cpp_compat/matrix.hlsl" namespace nbl { namespace hlsl { #line 61 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/cpp_compat/matrix.hlsl" typedef matrix<bool, 4, 4> bool4x4; typedef matrix<bool, 4, 3> bool4x3; typedef matrix<bool, 4, 2> bool4x2; typedef matrix<bool, 3, 4> bool3x4; typedef matrix<bool, 3, 3> bool3x3; typedef matrix<bool, 3, 2> bool3x2; typedef matrix<bool, 2, 4> bool2x4; typedef matrix<bool, 2, 3> bool2x3; typedef matrix<bool, 2, 2> bool2x2;; typedef matrix<int16_t, 4, 4> int16_t4x4; typedef matrix<int16_t, 4, 3> int16_t4x3; typedef matrix<int16_t, 4, 2> int16_t4x2; typedef matrix<int16_t, 3, 4> int16_t3x4; typedef matrix<int16_t, 3, 3> int16_t3x3; typedef matrix<int16_t, 3, 2> int16_t3x2; typedef matrix<int16_t, 2, 4> int16_t2x4; typedef matrix<int16_t, 2, 3> int16_t2x3; typedef matrix<int16_t, 2, 2> int16_t2x2;; typedef matrix<int32_t, 4, 4> int32_t4x4; typedef matrix<int32_t, 4, 3> int32_t4x3; typedef matrix<int32_t, 4, 2> int32_t4x2; typedef matrix<int32_t, 3, 4> int32_t3x4; typedef matrix<int32_t, 3, 3> int32_t3x3; typedef matrix<int32_t, 3, 2> int32_t3x2; typedef matrix<int32_t, 2, 4> int32_t2x4; typedef matrix<int32_t, 2, 3> int32_t2x3; typedef matrix<int32_t, 2, 2> int32_t2x2;; typedef matrix<int64_t, 4, 4> int64_t4x4; typedef matrix<int64_t, 4, 3> int64_t4x3; typedef matrix<int64_t, 4, 2> int64_t4x2; typedef matrix<int64_t, 3, 4> int64_t3x4; typedef matrix<int64_t, 3, 3> int64_t3x3; typedef matrix<int64_t, 3, 2> int64_t3x2; typedef matrix<int64_t, 2, 4> int64_t2x4; typedef matrix<int64_t, 2, 3> int64_t2x3; typedef matrix<int64_t, 2, 2> int64_t2x2;; typedef matrix<uint16_t, 4, 4> uint16_t4x4; typedef matrix<uint16_t, 4, 3> uint16_t4x3; typedef matrix<uint16_t, 4, 2> uint16_t4x2; typedef matrix<uint16_t, 3, 4> uint16_t3x4; typedef matrix<uint16_t, 3, 3> uint16_t3x3; typedef matrix<uint16_t, 3, 2> uint16_t3x2; typedef matrix<uint16_t, 2, 4> uint16_t2x4; typedef matrix<uint16_t, 2, 3> uint16_t2x3; typedef matrix<uint16_t, 2, 2> uint16_t2x2;; typedef matrix<uint32_t, 4, 4> uint32_t4x4; typedef matrix<uint32_t, 4, 3> uint32_t4x3; typedef matrix<uint32_t, 4, 2> uint32_t4x2; typedef matrix<uint32_t, 3, 4> uint32_t3x4; typedef matrix<uint32_t, 3, 3> uint32_t3x3; typedef matrix<uint32_t, 3, 2> uint32_t3x2; typedef matrix<uint32_t, 2, 4> uint32_t2x4; typedef matrix<uint32_t, 2, 3> uint32_t2x3; typedef matrix<uint32_t, 2, 2> uint32_t2x2;; typedef matrix<uint64_t, 4, 4> uint64_t4x4; typedef matrix<uint64_t, 4, 3> uint64_t4x3; typedef matrix<uint64_t, 4, 2> uint64_t4x2; typedef matrix<uint64_t, 3, 4> uint64_t3x4; typedef matrix<uint64_t, 3, 3> uint64_t3x3; typedef matrix<uint64_t, 3, 2> uint64_t3x2; typedef matrix<uint64_t, 2, 4> uint64_t2x4; typedef matrix<uint64_t, 2, 3> uint64_t2x3; typedef matrix<uint64_t, 2, 2> uint64_t2x2;; typedef matrix<float16_t, 4, 4> float16_t4x4; typedef matrix<float16_t, 4, 3> float16_t4x3; typedef matrix<float16_t, 4, 2> float16_t4x2; typedef matrix<float16_t, 3, 4> float16_t3x4; typedef matrix<float16_t, 3, 3> float16_t3x3; typedef matrix<float16_t, 3, 2> float16_t3x2; typedef matrix<float16_t, 2, 4> float16_t2x4; typedef matrix<float16_t, 2, 3> float16_t2x3; typedef matrix<float16_t, 2, 2> float16_t2x2;; typedef matrix<float32_t, 4, 4> float32_t4x4; typedef matrix<float32_t, 4, 3> float32_t4x3; typedef matrix<float32_t, 4, 2> float32_t4x2; typedef matrix<float32_t, 3, 4> float32_t3x4; typedef matrix<float32_t, 3, 3> float32_t3x3; typedef matrix<float32_t, 3, 2> float32_t3x2; typedef matrix<float32_t, 2, 4> float32_t2x4; typedef matrix<float32_t, 2, 3> float32_t2x3; typedef matrix<float32_t, 2, 2> float32_t2x2;; typedef matrix<float64_t, 4, 4> float64_t4x4; typedef matrix<float64_t, 4, 3> float64_t4x3; typedef matrix<float64_t, 4, 2> float64_t4x2; typedef matrix<float64_t, 3, 4> float64_t3x4; typedef matrix<float64_t, 3, 3> float64_t3x3; typedef matrix<float64_t, 3, 2> float64_t3x2; typedef matrix<float64_t, 2, 4> float64_t2x4; typedef matrix<float64_t, 2, 3> float64_t2x3; typedef matrix<float64_t, 2, 2> float64_t2x2;; } #line 89 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/cpp_compat/matrix.hlsl" } #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/type_traits.hlsl" // Copyright (C) 2022 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 7 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/type_traits.hlsl" // C++ headers #line 16 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/type_traits.hlsl" // Include only concept stuff that does not rely on type_traits #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts/impl/base.hlsl" // Copyright (C) 2023-2024 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 19 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/type_traits.hlsl" // Since HLSL currently doesnt allow type aliases we declare them as seperate structs thus they are (WORKAROUND)s /* // helper class template<class T, T v> struct integral_constant; (DONE) template<bool B> using bool_constant = integral_constant<bool, B>; (WORKDAROUND) using true_type = bool_constant<true>; (WORKDAROUND) using false_type = bool_constant<false>; (WORKDAROUND) // primary type categories template<class T> struct is_void; (DONE) template<class T> struct is_null_pointer; (NOT-APPLICABLE) template<class T> struct is_integral; (DONE) template<class T> struct is_floating_point; (DONE) template<class T> struct is_array; (DONE) template<class T> struct is_pointer; (TODO) template<class T> struct is_lvalue_reference; (TODO) template<class T> struct is_rvalue_reference; (TODO) template<class T> struct is_member_object_pointer; (TODO) template<class T> struct is_member_function_pointer; (TODO) template<class T> struct is_enum; (NOT-APPLICABLE) template<class T> struct is_union; (NOT-APPLICABLE) template<class T> struct is_class; (NOT-APPLICABLE) template<class T> struct is_function; (NOT-APPLICABLE) // composite type categories template<class T> struct is_reference; (TODO) template<class T> struct is_arithmetic; (DONE) template<class T> struct is_fundamental; (DONE) template<class T> struct is_object; (TODO) C++ spec defines object as: void is not an object int is object int& is not an object int* is object int*& is not an object cls is object cls& is not an object cls* is object int() is not an object int(*)() is object int(&)() is not an object basically !(is_reference || is_void || is_function) template<class T> struct is_scalar; (DONE) template<class T> struct is_compound; (DONE) template<class T> struct is_member_pointer; (TODO) // type properties template<class T> struct is_const; (DONE) template<class T> struct is_volatile; (DONE) template<class T> struct is_trivial; (EVERYTHING IS) template<class T> struct is_trivially_copyable; (EVERYTHING IS) template<class T> struct is_standard_layout; (APPLICABLE BUT IMPOSSIBLE TO TEST WITHOUT REFLECTION) template<class T> struct is_empty; (DONE? sizeof(T) == 0) template<class T> struct is_polymorphic; (NOTHING IS) template<class T> struct is_abstract; (NOTHING IS) template<class T> struct is_final; (NOTHING IS until they add the final keyword) template<class T> struct is_aggregate; (DONE) template<class T> struct is_signed; (DONE) template<class T> struct is_unsigned; (DONE) template<class T> struct is_bounded_array(DONE); template<class T> struct is_unbounded_array(DONE); template<class T> struct is_scoped_enum; (NOT-APPLICABLE) // type property queries template<class T> struct alignment_of; (SPECIALIZED FOR REGISTERED TYPES) template<class T> struct rank; (DONE) template<class T, unsigned I = 0> struct extent; (DONE) // type relations template<class T, class U> struct is_same; (DONE) template<class Base, class Derived> struct is_base_of; (TODO) template<class From, class To> struct is_convertible; (TODO) template<class From, class To> struct is_nothrow_convertible; (TODO: ALIAS OF is_convertible) template<class T, class U> struct is_layout_compatible; (TODO) template<class Base, class Derived> struct is_pointer_interconvertible_base_of; (NOT-APPLICABLE) NO FOLD EXPRESSIONS IN HLSL! template<class Fn, class... ArgTypes> struct is_invocable; template<class R, class Fn, class... ArgTypes> struct is_invocable_r; template<class Fn, class... ArgTypes> struct is_nothrow_invocable; template<class R, class Fn, class... ArgTypes> struct is_nothrow_invocable_r; // const-volatile modifications template<class T> struct remove_const; (DONE) template<class T> struct remove_volatile; (DONE) template<class T> struct remove_cv; (DONE) template<class T> struct add_const; (DONE) template<class T> struct add_volatile; (DONE) template<class T> struct add_cv; (DONE) // reference modifications template<class T> struct remove_reference; (DONE BUT DONT USE) template<class T> struct add_lvalue_reference; (DONE BUT DONT USE) template<class T> struct add_rvalue_reference; (TODO) // sign modifications template<class T> struct make_signed; (DONE) template<class T> struct make_unsigned; (DONE) // array modifications template<class T> struct remove_extent; (DONE) template<class T> struct remove_all_extents; (DONE) // pointer modifications template<class T> struct remove_pointer; (NOT-POSSIBLE UNTIL PSUEDO PTRS ARE IMPLEMENTED) template<class T> struct add_pointer; (NOT-POSSIBLE UNTIL PSUEDO PTRS ARE IMPLEMENTED) // other transformations template<class T> struct type_identity; (DONE) template<class T> struct remove_cvref; (DONE) template<class T> struct decay; (TODO) template<bool, class T = void> struct enable_if; (NOT-APPLICABLE) template<bool, class T, class F> struct conditional; (DONE) template<class... T> struct common_type; (NOT-APPLICABLE) template<class T, class U, template<class> class TQual, template<class> class UQual> struct basic_common_reference { }; (NOT-APPLICABLE) template<class... T> struct common_reference; (NOT-APPLICABLE) template<class T> struct underlying_type; template<class Fn, class... ArgTypes> struct invoke_result; template<class T> struct unwrap_reference; (TODO) template<class T> struct unwrap_ref_decay; (TODO) template<class...> using void_t = void; (VARIADICS NOT SUPPORTED USE `make_void` INSTEAD) NO FOLD EXPRESSIONS IN HLSL! // logical operator traits template<class... B> struct conjunction; template<class... B> struct disjunction; template<class B> struct negation; */ namespace nbl { namespace hlsl { // namespace impl { template<template<class> class Trait, class T> struct base_type_forwarder : Trait<T> {}; template<template<class> class Trait, class T, uint16_t N> struct base_type_forwarder<Trait,vector<T,N> > : Trait<T> {}; template<template<class> class Trait, class T, uint16_t N, uint16_t M> struct base_type_forwarder<Trait,matrix<T,N,M> > : Trait<T> {}; } // template<class> struct make_void { using type = void; }; #line 181 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/type_traits.hlsl" template<class T> struct type_identity { using type = T; }; namespace impl { template<class> struct remove_reference; } template<class T> struct remove_const : type_identity<T> {}; template<class T> struct remove_const<const T> : type_identity<T> {}; template<class T> struct remove_volatile : type_identity<T> {}; template<class T> struct remove_volatile<volatile T> : type_identity<T> {}; template<class T> struct remove_cv : type_identity<T> {}; template<class T> struct remove_cv<const T> : type_identity<T> {}; template<class T> struct remove_cv<volatile T> : type_identity<T> {}; template<class T> struct remove_cv<const volatile T> : type_identity<T> {}; template<class T> struct remove_cvref : remove_cv<typename impl::remove_reference<T>::type> {}; template<class T> struct add_const : type_identity<const T> {}; template<class T> struct add_volatile : type_identity<volatile T> {}; template<class T> struct add_cv : type_identity<const volatile T> {}; template<class T, T val> struct integral_constant { const static T value = val; using value_type = T; }; template<bool val> struct bool_constant : integral_constant<bool, val> {}; struct true_type : bool_constant<true> {}; struct false_type : bool_constant<false> {}; template<bool C, class T, class F> struct conditional : type_identity<T> {}; template<class T, class F> struct conditional<false, T, F> : type_identity<F> {}; template<class A, class B> struct is_same : bool_constant<false> {}; template<class A> struct is_same<A,A> : bool_constant<true> {}; template<class T> struct is_void : bool_constant<is_same<typename remove_cv<T>::type, void>::value> {}; template<class T> struct is_bounded_array : bool_constant<false> {}; template<class T, uint32_t count> struct is_bounded_array<T[count]> : bool_constant<true>{}; template<class T> struct is_unbounded_array : bool_constant<false>{}; template<class T> struct is_unbounded_array<T[]> : bool_constant<true>{}; template<class T> struct is_array : bool_constant<is_bounded_array<T>::value || is_unbounded_array<T>::value> {}; namespace impl { // need this crutch because we can't make `#define typeid` work both on expression and types template<typename T> struct typeid_t; template<typename T, T v> struct function_info : type_identity<void> {}; template<class T> struct is_unsigned : bool_constant< is_same<T, bool>::value || is_same<T, uint16_t>::value || is_same<T, uint32_t>::value || is_same<T, uint64_t>::value > {}; template<class T> struct is_integral : bool_constant< is_same<T, bool>::value || is_same<T, uint16_t>::value || is_same<T, uint32_t>::value || is_same<T, uint64_t>::value || is_same<T, int16_t>::value || is_same<T, int32_t>::value || is_same<T, int64_t>::value > {}; template<class T> struct is_floating_point : bool_constant< is_same<T, half>::value || is_same<T, float>::value || is_same<T, double>::value > {}; template<class T> struct is_signed : bool_constant< is_same<T, int16_t>::value || is_same<T, int32_t>::value || is_same<T, int64_t>::value || is_floating_point<T>::value > {}; } //! For inline SPIR-V template<typename T> struct is_vk_Literal : false_type {}; template<typename IC> struct is_vk_Literal<vk::Literal<IC> > : true_type { using type = IC; }; template<typename T> const static bool is_vk_Literal_v = is_vk_Literal<T>::value; // DXC doesn't support variadics, matches need to be declared in reverse, most args to least (in case templates have defaults0 #line 314 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/type_traits.hlsl" template<typename T> struct is_spirv_opaque_type : false_type {}; #line 318 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/type_traits.hlsl" template<uint32_t OpType ,typename T0 ,typename T1 ,typename T2> struct is_spirv_opaque_type<vk::SpirvOpaqueType<OpType ,T0 ,T1 ,T2> > : true_type {}; template<uint32_t OpType ,typename T0 ,typename T1> struct is_spirv_opaque_type<vk::SpirvOpaqueType<OpType ,T0 ,T1> > : true_type {}; template<uint32_t OpType ,typename T0> struct is_spirv_opaque_type<vk::SpirvOpaqueType<OpType ,T0> > : true_type {}; template<uint32_t OpType > struct is_spirv_opaque_type<vk::SpirvOpaqueType<OpType > > : true_type {}; template<class T> const static bool is_spirv_opaque_type_v = is_spirv_opaque_type<T>::value; template<typename T> struct is_spirv_storable_type : false_type {}; #line 330 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/type_traits.hlsl" template<uint32_t OpType, uint32_t Size, uint32_t Alignment ,typename T0 ,typename T1 ,typename T2> struct is_spirv_storable_type<vk::SpirvType<OpType,Size,Alignment ,T0 ,T1 ,T2> > : true_type {}; template<uint32_t OpType, uint32_t Size, uint32_t Alignment ,typename T0 ,typename T1> struct is_spirv_storable_type<vk::SpirvType<OpType,Size,Alignment ,T0 ,T1> > : true_type {}; template<uint32_t OpType, uint32_t Size, uint32_t Alignment ,typename T0> struct is_spirv_storable_type<vk::SpirvType<OpType,Size,Alignment ,T0> > : true_type {}; template<uint32_t OpType, uint32_t Size, uint32_t Alignment > struct is_spirv_storable_type<vk::SpirvType<OpType,Size,Alignment > > : true_type {}; template<class T> const static bool is_spirv_storable_type_v = is_spirv_storable_type<T>::value; template<typename T> struct is_spirv_type : bool_constant<is_spirv_opaque_type_v<T>||is_spirv_storable_type_v<T> > {}; template<class T> const static bool is_spirv_type_v = is_spirv_type<T>::value; template<class T> struct is_unsigned : impl::base_type_forwarder<impl::is_unsigned, typename remove_cv<T>::type> {}; template<class T> struct is_integral : impl::base_type_forwarder<impl::is_integral, typename remove_cv<T>::type> {}; template<class T> struct is_floating_point : impl::base_type_forwarder<impl::is_floating_point, typename remove_cv<T>::type> {}; template<class T> struct is_signed : impl::base_type_forwarder<impl::is_signed, typename remove_cv<T>::type> {}; template<class T> struct is_scalar : bool_constant< impl::is_integral<typename remove_cv<T>::type>::value || impl::is_floating_point<typename remove_cv<T>::type>::value > {}; template<class T> struct is_const : bool_constant<false> {}; template<class T> struct is_const<const T> : bool_constant<true> {}; template<class T> struct is_volatile : bool_constant<false> {}; template<class T> struct is_volatile<volatile T> : bool_constant<true> {}; template<class> struct is_trivial : bool_constant<true> {}; template<class> struct is_trivially_copyable : bool_constant<true> {}; // this implementation is fragile template<class T> struct is_empty : bool_constant<0==sizeof(T)> {}; template<class> struct is_polymorphic : bool_constant<false> {}; template<class> struct is_abstract : bool_constant<false> {}; template<class> struct is_final : bool_constant<false> {}; template <class T> struct is_fundamental : bool_constant< is_scalar<T>::value || is_void<T>::value > {}; template <class T> struct is_compound : bool_constant<!is_fundamental<T>::value> {}; template <class T> struct is_aggregate : is_compound<T> {}; template<class T> struct rank : integral_constant<uint64_t, 0> { }; template<class T, uint64_t N> struct rank<T[N]> : integral_constant<uint64_t, 1 + rank<T>::value> { }; template<class T> struct rank<T[]> : integral_constant<uint64_t, 1 + rank<T>::value> { }; template<class T, uint32_t I = 0 ,typename __requires=void> struct extent : integral_constant<uint64_t, 0> {}; template<class T, uint64_t N> struct extent<T[N], 0> : integral_constant<uint64_t, N> {}; template<class T, uint64_t N, uint32_t I> struct extent<T[N], I> : integral_constant<uint64_t,extent<T, I - 1>::value> {}; template<class T, uint32_t I> struct extent<T[], I> : integral_constant<uint64_t,extent<T, I - 1>::value> {}; template<bool B, class T = void> struct enable_if {}; template<class T> struct enable_if<true, T> : type_identity<T> {}; // DXC sometimes doesn't report sizeof properly template<class T> struct size_of { const static uint64_t value = sizeof(T); }; template<class T> struct alignment_of; // reference stuff needed for semantics // not for "human consumption" // dxc doesnt actually allow variables to be references // every reference is treated as having 'restrict' qualifier // https://godbolt.org/z/dsj99fY96 namespace impl { template<typename,class=void> struct is_reference : bool_constant<true> { }; template<typename T> struct is_reference<T,typename make_void<T[1]>::type> : bool_constant<false> { }; template<class T, bool = is_reference<T>::value> struct add_reference_helper : type_identity<T> {}; template<class T> struct add_reference_helper<T, false> { static T member[1]; using type = __decltype(member[0]); }; template<class T> struct add_lvalue_reference : add_reference_helper<T> {}; template<typename T> T remove_reference_impl(T v) { return v; } template<typename T, bool = is_reference<T>::value> struct remove_reference_helper : type_identity<T> {}; template<typename T> struct remove_reference_helper<T, true> { static T member; using type = __decltype(remove_reference_impl(member)); }; template<typename T> struct remove_reference : remove_reference_helper<T> {}; } template<class T> struct remove_extent : type_identity<T> {}; template<class T, uint32_t I> struct remove_extent<T[I]> : type_identity<T> {}; template<class T> struct remove_extent<T[]> : type_identity<T> {}; template<typename T, int N> struct remove_extent<vector<T, N> > : type_identity<T> {}; template<typename T, int N, int M> struct remove_extent<matrix<T, N, M> > : type_identity<vector<T, N> > {}; template <class T> struct remove_all_extents : type_identity<T> {}; template <class T, uint32_t I> struct remove_all_extents<T[I]> : type_identity<typename remove_all_extents<T>::type> {}; template <class T> struct remove_all_extents<T[]> : type_identity<typename remove_all_extents<T>::type> {}; namespace impl { template<uint32_t sz> struct int_type : conditional<8==sz, int64_t, typename conditional<4==sz, int32_t, int16_t>::type>{}; template<uint32_t sz> struct uint_type : conditional<8==sz, uint64_t, typename conditional<4==sz, uint32_t, uint16_t>::type>{}; } template<class T> struct make_signed : impl::int_type<sizeof(T)> { _Static_assert(is_integral<T>::value && !is_same<typename remove_cv<T>::type, bool>::value, "make_signed<T> requires that T shall be a (possibly cv-qualified) " "integral type or enumeration but not a bool type."); }; template<class T> struct make_unsigned : impl::uint_type<sizeof(T)> { _Static_assert(is_integral<T>::value && !is_same<typename remove_cv<T>::type, bool>::value, "make_unsigned<T> requires that T shall be a (possibly cv-qualified) " "integral type or enumeration but not a bool type."); }; #line 659 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/type_traits.hlsl" // Template Types template<bool B, class T = void> using enable_if_t = typename enable_if<B,T>::type; template<bool C, class T, class F> using conditional_t = typename conditional<C,T,F>::type; // Template Variables template<class T, T val> const static T integral_constant_v = integral_constant<T, val>::value; template<typename A, typename B> const static bool is_same_v = is_same<A, B>::value; template<class T> const static bool is_unsigned_v = is_unsigned<T>::value; template<class T> const static bool is_integral_v = is_integral<T>::value; template<class T> const static bool is_floating_point_v = is_floating_point<T>::value; template<class T> const static bool is_signed_v = is_signed<T>::value; template<class T> const static bool is_scalar_v = is_scalar<T>::value; template<class T> const static uint64_t size_of_v = size_of<T>::value; template<class T> const static uint32_t alignment_of_v = alignment_of<T>::value; template<class T, uint32_t N = 0> const static uint64_t extent_v = extent<T, N>::value; template<typename T> const static bool is_fundamental_v = is_fundamental<T>::value; // Overlapping definitions template<typename T> using make_void_t = typename make_void<T>::type; template<typename T> using make_signed_t = typename make_signed<T>::type; template<typename T> using make_unsigned_t = typename make_unsigned<T>::type; template<bool C, typename T, T A, T B> struct conditional_value { const static T value = C ? A : B; }; template<class T> struct is_vector : bool_constant<false> {}; template<class T> struct is_matrix : bool_constant<false> {}; template<class T, uint32_t N> struct is_vector<vector<T, N> > : bool_constant<true> {}; template<typename T> const static bool is_vector_v = is_vector<T>::value; #line 724 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/type_traits.hlsl" template<class T, uint32_t N, uint32_t M> struct is_matrix<matrix<T, N, M> > : bool_constant<true> {}; template<class T> const static bool is_matrix_v = is_matrix<T>::value; template<typename T,bool=is_scalar<T>::value> struct scalar_type { using type = void; }; template<typename T> struct scalar_type<T,true> { using type = T; }; template<typename T, uint16_t N> struct scalar_type<vector<T,N>,false> { using type = T; }; template<typename T, uint16_t N, uint16_t M> struct scalar_type<matrix<T,N,M>,false> { using type = T; }; template<typename T> using scalar_type_t = typename scalar_type<T>::type; template<uint16_t bytesize> struct integer_of_size { using type = void; }; #line 771 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/type_traits.hlsl" template<> struct integer_of_size<2> { using type = int16_t; }; template<> struct integer_of_size<4> { using type = int32_t; }; template<> struct integer_of_size<8> { using type = int64_t; }; template<uint16_t bytesize> using integer_of_size_t = typename integer_of_size<bytesize>::type; template<uint16_t bytesize> struct unsigned_integer_of_size { using type = void; }; #line 801 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/type_traits.hlsl" template<> struct unsigned_integer_of_size<2> { using type = uint16_t; }; template<> struct unsigned_integer_of_size<4> { using type = uint32_t; }; template<> struct unsigned_integer_of_size<8> { using type = uint64_t; }; template<uint16_t bytesize> using unsigned_integer_of_size_t = typename unsigned_integer_of_size<bytesize>::type; template<uint16_t bytesize> struct float_of_size { using type = void; }; template<> struct float_of_size<2> { using type = float16_t; }; template<> struct float_of_size<4> { using type = float32_t; }; template<> struct float_of_size<8> { using type = float64_t; }; template<uint16_t bytesize> using float_of_size_t = typename float_of_size<bytesize>::type; template<typename T, int N> struct extent<vector<T, N>, 0> : integral_constant<uint64_t, N> {}; template<typename T, int N, int M> struct extent<matrix<T, N, M>, 0> : integral_constant<uint64_t, N> {}; template<typename T, int N, int M> struct extent<matrix<T, N, M>, 1> : integral_constant<uint64_t, M> {}; } } // deal with typetraits, for now we rely on Clang/DXC internal __decltype(), if it breaks we revert to commit e4ab38ca227b15b2c79641c39161f1f922b779a3 #line 859 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/type_traits.hlsl" // shoudl really return a std::type_info like struct or something, but no `constexpr` and unsure whether its possible to have a `const static SomeStruct` makes it hard to do... // Found a bug in Boost.Wave, try to avoid multi-line macros https://github.com/boostorg/wave/issues/195 #line 872 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/type_traits.hlsl" // TODO: find out how to do it such that we don't get duplicate definition if we use two function identifiers with same signature // TODO: ideally we'd like to call NBL_REGISTER_FUN_TYPE under the hood, but we can't right now. Also we have a bigger problem, the passing of the function identifier as the second template parameter doesn't work :( /* template<> struct function_info<__decltype(fn),fn> { using type = __decltype(fn); static const uint32_t address = __COUNTER__; }; }}}} */ // builtins #line 900 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/type_traits.hlsl" namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<int16_t > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<int16_t > : integral_constant<uint32_t, sizeof(int16_t) > {}; template<> struct alignment_of<const int16_t > : integral_constant<uint32_t, sizeof(int16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<int16_t >::type> : integral_constant<uint32_t, sizeof(int16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const int16_t >::type> : integral_constant<uint32_t, sizeof(int16_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<int16_t1 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<int16_t1 > : integral_constant<uint32_t, sizeof(int16_t) > {}; template<> struct alignment_of<const int16_t1 > : integral_constant<uint32_t, sizeof(int16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<int16_t1 >::type> : integral_constant<uint32_t, sizeof(int16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const int16_t1 >::type> : integral_constant<uint32_t, sizeof(int16_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<int16_t2 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<int16_t2 > : integral_constant<uint32_t, sizeof(int16_t) > {}; template<> struct alignment_of<const int16_t2 > : integral_constant<uint32_t, sizeof(int16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<int16_t2 >::type> : integral_constant<uint32_t, sizeof(int16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const int16_t2 >::type> : integral_constant<uint32_t, sizeof(int16_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<int16_t2x4 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<int16_t2x4 > : integral_constant<uint32_t, sizeof(int16_t) > {}; template<> struct alignment_of<const int16_t2x4 > : integral_constant<uint32_t, sizeof(int16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<int16_t2x4 >::type> : integral_constant<uint32_t, sizeof(int16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const int16_t2x4 >::type> : integral_constant<uint32_t, sizeof(int16_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<int16_t2x3 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<int16_t2x3 > : integral_constant<uint32_t, sizeof(int16_t) > {}; template<> struct alignment_of<const int16_t2x3 > : integral_constant<uint32_t, sizeof(int16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<int16_t2x3 >::type> : integral_constant<uint32_t, sizeof(int16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const int16_t2x3 >::type> : integral_constant<uint32_t, sizeof(int16_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<int16_t2x2 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<int16_t2x2 > : integral_constant<uint32_t, sizeof(int16_t) > {}; template<> struct alignment_of<const int16_t2x2 > : integral_constant<uint32_t, sizeof(int16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<int16_t2x2 >::type> : integral_constant<uint32_t, sizeof(int16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const int16_t2x2 >::type> : integral_constant<uint32_t, sizeof(int16_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<int16_t3 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<int16_t3 > : integral_constant<uint32_t, sizeof(int16_t) > {}; template<> struct alignment_of<const int16_t3 > : integral_constant<uint32_t, sizeof(int16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<int16_t3 >::type> : integral_constant<uint32_t, sizeof(int16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const int16_t3 >::type> : integral_constant<uint32_t, sizeof(int16_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<int16_t3x4 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<int16_t3x4 > : integral_constant<uint32_t, sizeof(int16_t) > {}; template<> struct alignment_of<const int16_t3x4 > : integral_constant<uint32_t, sizeof(int16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<int16_t3x4 >::type> : integral_constant<uint32_t, sizeof(int16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const int16_t3x4 >::type> : integral_constant<uint32_t, sizeof(int16_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<int16_t3x3 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<int16_t3x3 > : integral_constant<uint32_t, sizeof(int16_t) > {}; template<> struct alignment_of<const int16_t3x3 > : integral_constant<uint32_t, sizeof(int16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<int16_t3x3 >::type> : integral_constant<uint32_t, sizeof(int16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const int16_t3x3 >::type> : integral_constant<uint32_t, sizeof(int16_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<int16_t3x2 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<int16_t3x2 > : integral_constant<uint32_t, sizeof(int16_t) > {}; template<> struct alignment_of<const int16_t3x2 > : integral_constant<uint32_t, sizeof(int16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<int16_t3x2 >::type> : integral_constant<uint32_t, sizeof(int16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const int16_t3x2 >::type> : integral_constant<uint32_t, sizeof(int16_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<int16_t4 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<int16_t4 > : integral_constant<uint32_t, sizeof(int16_t) > {}; template<> struct alignment_of<const int16_t4 > : integral_constant<uint32_t, sizeof(int16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<int16_t4 >::type> : integral_constant<uint32_t, sizeof(int16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const int16_t4 >::type> : integral_constant<uint32_t, sizeof(int16_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<int16_t4x4 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<int16_t4x4 > : integral_constant<uint32_t, sizeof(int16_t) > {}; template<> struct alignment_of<const int16_t4x4 > : integral_constant<uint32_t, sizeof(int16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<int16_t4x4 >::type> : integral_constant<uint32_t, sizeof(int16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const int16_t4x4 >::type> : integral_constant<uint32_t, sizeof(int16_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<int16_t4x3 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<int16_t4x3 > : integral_constant<uint32_t, sizeof(int16_t) > {}; template<> struct alignment_of<const int16_t4x3 > : integral_constant<uint32_t, sizeof(int16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<int16_t4x3 >::type> : integral_constant<uint32_t, sizeof(int16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const int16_t4x3 >::type> : integral_constant<uint32_t, sizeof(int16_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<int16_t4x2 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<int16_t4x2 > : integral_constant<uint32_t, sizeof(int16_t) > {}; template<> struct alignment_of<const int16_t4x2 > : integral_constant<uint32_t, sizeof(int16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<int16_t4x2 >::type> : integral_constant<uint32_t, sizeof(int16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const int16_t4x2 >::type> : integral_constant<uint32_t, sizeof(int16_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<int32_t > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<int32_t > : integral_constant<uint32_t, sizeof(int32_t) > {}; template<> struct alignment_of<const int32_t > : integral_constant<uint32_t, sizeof(int32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<int32_t >::type> : integral_constant<uint32_t, sizeof(int32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const int32_t >::type> : integral_constant<uint32_t, sizeof(int32_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<int32_t1 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<int32_t1 > : integral_constant<uint32_t, sizeof(int32_t) > {}; template<> struct alignment_of<const int32_t1 > : integral_constant<uint32_t, sizeof(int32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<int32_t1 >::type> : integral_constant<uint32_t, sizeof(int32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const int32_t1 >::type> : integral_constant<uint32_t, sizeof(int32_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<int32_t2 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<int32_t2 > : integral_constant<uint32_t, sizeof(int32_t) > {}; template<> struct alignment_of<const int32_t2 > : integral_constant<uint32_t, sizeof(int32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<int32_t2 >::type> : integral_constant<uint32_t, sizeof(int32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const int32_t2 >::type> : integral_constant<uint32_t, sizeof(int32_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<int32_t2x4 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<int32_t2x4 > : integral_constant<uint32_t, sizeof(int32_t) > {}; template<> struct alignment_of<const int32_t2x4 > : integral_constant<uint32_t, sizeof(int32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<int32_t2x4 >::type> : integral_constant<uint32_t, sizeof(int32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const int32_t2x4 >::type> : integral_constant<uint32_t, sizeof(int32_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<int32_t2x3 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<int32_t2x3 > : integral_constant<uint32_t, sizeof(int32_t) > {}; template<> struct alignment_of<const int32_t2x3 > : integral_constant<uint32_t, sizeof(int32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<int32_t2x3 >::type> : integral_constant<uint32_t, sizeof(int32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const int32_t2x3 >::type> : integral_constant<uint32_t, sizeof(int32_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<int32_t2x2 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<int32_t2x2 > : integral_constant<uint32_t, sizeof(int32_t) > {}; template<> struct alignment_of<const int32_t2x2 > : integral_constant<uint32_t, sizeof(int32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<int32_t2x2 >::type> : integral_constant<uint32_t, sizeof(int32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const int32_t2x2 >::type> : integral_constant<uint32_t, sizeof(int32_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<int32_t3 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<int32_t3 > : integral_constant<uint32_t, sizeof(int32_t) > {}; template<> struct alignment_of<const int32_t3 > : integral_constant<uint32_t, sizeof(int32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<int32_t3 >::type> : integral_constant<uint32_t, sizeof(int32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const int32_t3 >::type> : integral_constant<uint32_t, sizeof(int32_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<int32_t3x4 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<int32_t3x4 > : integral_constant<uint32_t, sizeof(int32_t) > {}; template<> struct alignment_of<const int32_t3x4 > : integral_constant<uint32_t, sizeof(int32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<int32_t3x4 >::type> : integral_constant<uint32_t, sizeof(int32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const int32_t3x4 >::type> : integral_constant<uint32_t, sizeof(int32_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<int32_t3x3 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<int32_t3x3 > : integral_constant<uint32_t, sizeof(int32_t) > {}; template<> struct alignment_of<const int32_t3x3 > : integral_constant<uint32_t, sizeof(int32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<int32_t3x3 >::type> : integral_constant<uint32_t, sizeof(int32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const int32_t3x3 >::type> : integral_constant<uint32_t, sizeof(int32_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<int32_t3x2 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<int32_t3x2 > : integral_constant<uint32_t, sizeof(int32_t) > {}; template<> struct alignment_of<const int32_t3x2 > : integral_constant<uint32_t, sizeof(int32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<int32_t3x2 >::type> : integral_constant<uint32_t, sizeof(int32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const int32_t3x2 >::type> : integral_constant<uint32_t, sizeof(int32_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<int32_t4 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<int32_t4 > : integral_constant<uint32_t, sizeof(int32_t) > {}; template<> struct alignment_of<const int32_t4 > : integral_constant<uint32_t, sizeof(int32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<int32_t4 >::type> : integral_constant<uint32_t, sizeof(int32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const int32_t4 >::type> : integral_constant<uint32_t, sizeof(int32_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<int32_t4x4 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<int32_t4x4 > : integral_constant<uint32_t, sizeof(int32_t) > {}; template<> struct alignment_of<const int32_t4x4 > : integral_constant<uint32_t, sizeof(int32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<int32_t4x4 >::type> : integral_constant<uint32_t, sizeof(int32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const int32_t4x4 >::type> : integral_constant<uint32_t, sizeof(int32_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<int32_t4x3 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<int32_t4x3 > : integral_constant<uint32_t, sizeof(int32_t) > {}; template<> struct alignment_of<const int32_t4x3 > : integral_constant<uint32_t, sizeof(int32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<int32_t4x3 >::type> : integral_constant<uint32_t, sizeof(int32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const int32_t4x3 >::type> : integral_constant<uint32_t, sizeof(int32_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<int32_t4x2 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<int32_t4x2 > : integral_constant<uint32_t, sizeof(int32_t) > {}; template<> struct alignment_of<const int32_t4x2 > : integral_constant<uint32_t, sizeof(int32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<int32_t4x2 >::type> : integral_constant<uint32_t, sizeof(int32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const int32_t4x2 >::type> : integral_constant<uint32_t, sizeof(int32_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<int64_t > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<int64_t > : integral_constant<uint32_t, sizeof(int64_t) > {}; template<> struct alignment_of<const int64_t > : integral_constant<uint32_t, sizeof(int64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<int64_t >::type> : integral_constant<uint32_t, sizeof(int64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const int64_t >::type> : integral_constant<uint32_t, sizeof(int64_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<int64_t1 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<int64_t1 > : integral_constant<uint32_t, sizeof(int64_t) > {}; template<> struct alignment_of<const int64_t1 > : integral_constant<uint32_t, sizeof(int64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<int64_t1 >::type> : integral_constant<uint32_t, sizeof(int64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const int64_t1 >::type> : integral_constant<uint32_t, sizeof(int64_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<int64_t2 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<int64_t2 > : integral_constant<uint32_t, sizeof(int64_t) > {}; template<> struct alignment_of<const int64_t2 > : integral_constant<uint32_t, sizeof(int64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<int64_t2 >::type> : integral_constant<uint32_t, sizeof(int64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const int64_t2 >::type> : integral_constant<uint32_t, sizeof(int64_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<int64_t2x4 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<int64_t2x4 > : integral_constant<uint32_t, sizeof(int64_t) > {}; template<> struct alignment_of<const int64_t2x4 > : integral_constant<uint32_t, sizeof(int64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<int64_t2x4 >::type> : integral_constant<uint32_t, sizeof(int64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const int64_t2x4 >::type> : integral_constant<uint32_t, sizeof(int64_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<int64_t2x3 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<int64_t2x3 > : integral_constant<uint32_t, sizeof(int64_t) > {}; template<> struct alignment_of<const int64_t2x3 > : integral_constant<uint32_t, sizeof(int64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<int64_t2x3 >::type> : integral_constant<uint32_t, sizeof(int64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const int64_t2x3 >::type> : integral_constant<uint32_t, sizeof(int64_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<int64_t2x2 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<int64_t2x2 > : integral_constant<uint32_t, sizeof(int64_t) > {}; template<> struct alignment_of<const int64_t2x2 > : integral_constant<uint32_t, sizeof(int64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<int64_t2x2 >::type> : integral_constant<uint32_t, sizeof(int64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const int64_t2x2 >::type> : integral_constant<uint32_t, sizeof(int64_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<int64_t3 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<int64_t3 > : integral_constant<uint32_t, sizeof(int64_t) > {}; template<> struct alignment_of<const int64_t3 > : integral_constant<uint32_t, sizeof(int64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<int64_t3 >::type> : integral_constant<uint32_t, sizeof(int64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const int64_t3 >::type> : integral_constant<uint32_t, sizeof(int64_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<int64_t3x4 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<int64_t3x4 > : integral_constant<uint32_t, sizeof(int64_t) > {}; template<> struct alignment_of<const int64_t3x4 > : integral_constant<uint32_t, sizeof(int64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<int64_t3x4 >::type> : integral_constant<uint32_t, sizeof(int64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const int64_t3x4 >::type> : integral_constant<uint32_t, sizeof(int64_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<int64_t3x3 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<int64_t3x3 > : integral_constant<uint32_t, sizeof(int64_t) > {}; template<> struct alignment_of<const int64_t3x3 > : integral_constant<uint32_t, sizeof(int64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<int64_t3x3 >::type> : integral_constant<uint32_t, sizeof(int64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const int64_t3x3 >::type> : integral_constant<uint32_t, sizeof(int64_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<int64_t3x2 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<int64_t3x2 > : integral_constant<uint32_t, sizeof(int64_t) > {}; template<> struct alignment_of<const int64_t3x2 > : integral_constant<uint32_t, sizeof(int64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<int64_t3x2 >::type> : integral_constant<uint32_t, sizeof(int64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const int64_t3x2 >::type> : integral_constant<uint32_t, sizeof(int64_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<int64_t4 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<int64_t4 > : integral_constant<uint32_t, sizeof(int64_t) > {}; template<> struct alignment_of<const int64_t4 > : integral_constant<uint32_t, sizeof(int64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<int64_t4 >::type> : integral_constant<uint32_t, sizeof(int64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const int64_t4 >::type> : integral_constant<uint32_t, sizeof(int64_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<int64_t4x4 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<int64_t4x4 > : integral_constant<uint32_t, sizeof(int64_t) > {}; template<> struct alignment_of<const int64_t4x4 > : integral_constant<uint32_t, sizeof(int64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<int64_t4x4 >::type> : integral_constant<uint32_t, sizeof(int64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const int64_t4x4 >::type> : integral_constant<uint32_t, sizeof(int64_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<int64_t4x3 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<int64_t4x3 > : integral_constant<uint32_t, sizeof(int64_t) > {}; template<> struct alignment_of<const int64_t4x3 > : integral_constant<uint32_t, sizeof(int64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<int64_t4x3 >::type> : integral_constant<uint32_t, sizeof(int64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const int64_t4x3 >::type> : integral_constant<uint32_t, sizeof(int64_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<int64_t4x2 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<int64_t4x2 > : integral_constant<uint32_t, sizeof(int64_t) > {}; template<> struct alignment_of<const int64_t4x2 > : integral_constant<uint32_t, sizeof(int64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<int64_t4x2 >::type> : integral_constant<uint32_t, sizeof(int64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const int64_t4x2 >::type> : integral_constant<uint32_t, sizeof(int64_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<uint16_t > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<uint16_t > : integral_constant<uint32_t, sizeof(uint16_t) > {}; template<> struct alignment_of<const uint16_t > : integral_constant<uint32_t, sizeof(uint16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<uint16_t >::type> : integral_constant<uint32_t, sizeof(uint16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const uint16_t >::type> : integral_constant<uint32_t, sizeof(uint16_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<uint16_t1 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<uint16_t1 > : integral_constant<uint32_t, sizeof(uint16_t) > {}; template<> struct alignment_of<const uint16_t1 > : integral_constant<uint32_t, sizeof(uint16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<uint16_t1 >::type> : integral_constant<uint32_t, sizeof(uint16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const uint16_t1 >::type> : integral_constant<uint32_t, sizeof(uint16_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<uint16_t2 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<uint16_t2 > : integral_constant<uint32_t, sizeof(uint16_t) > {}; template<> struct alignment_of<const uint16_t2 > : integral_constant<uint32_t, sizeof(uint16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<uint16_t2 >::type> : integral_constant<uint32_t, sizeof(uint16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const uint16_t2 >::type> : integral_constant<uint32_t, sizeof(uint16_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<uint16_t2x4 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<uint16_t2x4 > : integral_constant<uint32_t, sizeof(uint16_t) > {}; template<> struct alignment_of<const uint16_t2x4 > : integral_constant<uint32_t, sizeof(uint16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<uint16_t2x4 >::type> : integral_constant<uint32_t, sizeof(uint16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const uint16_t2x4 >::type> : integral_constant<uint32_t, sizeof(uint16_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<uint16_t2x3 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<uint16_t2x3 > : integral_constant<uint32_t, sizeof(uint16_t) > {}; template<> struct alignment_of<const uint16_t2x3 > : integral_constant<uint32_t, sizeof(uint16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<uint16_t2x3 >::type> : integral_constant<uint32_t, sizeof(uint16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const uint16_t2x3 >::type> : integral_constant<uint32_t, sizeof(uint16_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<uint16_t2x2 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<uint16_t2x2 > : integral_constant<uint32_t, sizeof(uint16_t) > {}; template<> struct alignment_of<const uint16_t2x2 > : integral_constant<uint32_t, sizeof(uint16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<uint16_t2x2 >::type> : integral_constant<uint32_t, sizeof(uint16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const uint16_t2x2 >::type> : integral_constant<uint32_t, sizeof(uint16_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<uint16_t3 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<uint16_t3 > : integral_constant<uint32_t, sizeof(uint16_t) > {}; template<> struct alignment_of<const uint16_t3 > : integral_constant<uint32_t, sizeof(uint16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<uint16_t3 >::type> : integral_constant<uint32_t, sizeof(uint16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const uint16_t3 >::type> : integral_constant<uint32_t, sizeof(uint16_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<uint16_t3x4 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<uint16_t3x4 > : integral_constant<uint32_t, sizeof(uint16_t) > {}; template<> struct alignment_of<const uint16_t3x4 > : integral_constant<uint32_t, sizeof(uint16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<uint16_t3x4 >::type> : integral_constant<uint32_t, sizeof(uint16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const uint16_t3x4 >::type> : integral_constant<uint32_t, sizeof(uint16_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<uint16_t3x3 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<uint16_t3x3 > : integral_constant<uint32_t, sizeof(uint16_t) > {}; template<> struct alignment_of<const uint16_t3x3 > : integral_constant<uint32_t, sizeof(uint16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<uint16_t3x3 >::type> : integral_constant<uint32_t, sizeof(uint16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const uint16_t3x3 >::type> : integral_constant<uint32_t, sizeof(uint16_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<uint16_t3x2 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<uint16_t3x2 > : integral_constant<uint32_t, sizeof(uint16_t) > {}; template<> struct alignment_of<const uint16_t3x2 > : integral_constant<uint32_t, sizeof(uint16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<uint16_t3x2 >::type> : integral_constant<uint32_t, sizeof(uint16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const uint16_t3x2 >::type> : integral_constant<uint32_t, sizeof(uint16_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<uint16_t4 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<uint16_t4 > : integral_constant<uint32_t, sizeof(uint16_t) > {}; template<> struct alignment_of<const uint16_t4 > : integral_constant<uint32_t, sizeof(uint16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<uint16_t4 >::type> : integral_constant<uint32_t, sizeof(uint16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const uint16_t4 >::type> : integral_constant<uint32_t, sizeof(uint16_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<uint16_t4x4 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<uint16_t4x4 > : integral_constant<uint32_t, sizeof(uint16_t) > {}; template<> struct alignment_of<const uint16_t4x4 > : integral_constant<uint32_t, sizeof(uint16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<uint16_t4x4 >::type> : integral_constant<uint32_t, sizeof(uint16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const uint16_t4x4 >::type> : integral_constant<uint32_t, sizeof(uint16_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<uint16_t4x3 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<uint16_t4x3 > : integral_constant<uint32_t, sizeof(uint16_t) > {}; template<> struct alignment_of<const uint16_t4x3 > : integral_constant<uint32_t, sizeof(uint16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<uint16_t4x3 >::type> : integral_constant<uint32_t, sizeof(uint16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const uint16_t4x3 >::type> : integral_constant<uint32_t, sizeof(uint16_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<uint16_t4x2 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<uint16_t4x2 > : integral_constant<uint32_t, sizeof(uint16_t) > {}; template<> struct alignment_of<const uint16_t4x2 > : integral_constant<uint32_t, sizeof(uint16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<uint16_t4x2 >::type> : integral_constant<uint32_t, sizeof(uint16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const uint16_t4x2 >::type> : integral_constant<uint32_t, sizeof(uint16_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<uint32_t > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<uint32_t > : integral_constant<uint32_t, sizeof(uint32_t) > {}; template<> struct alignment_of<const uint32_t > : integral_constant<uint32_t, sizeof(uint32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<uint32_t >::type> : integral_constant<uint32_t, sizeof(uint32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const uint32_t >::type> : integral_constant<uint32_t, sizeof(uint32_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<uint32_t1 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<uint32_t1 > : integral_constant<uint32_t, sizeof(uint32_t) > {}; template<> struct alignment_of<const uint32_t1 > : integral_constant<uint32_t, sizeof(uint32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<uint32_t1 >::type> : integral_constant<uint32_t, sizeof(uint32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const uint32_t1 >::type> : integral_constant<uint32_t, sizeof(uint32_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<uint32_t2 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<uint32_t2 > : integral_constant<uint32_t, sizeof(uint32_t) > {}; template<> struct alignment_of<const uint32_t2 > : integral_constant<uint32_t, sizeof(uint32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<uint32_t2 >::type> : integral_constant<uint32_t, sizeof(uint32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const uint32_t2 >::type> : integral_constant<uint32_t, sizeof(uint32_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<uint32_t2x4 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<uint32_t2x4 > : integral_constant<uint32_t, sizeof(uint32_t) > {}; template<> struct alignment_of<const uint32_t2x4 > : integral_constant<uint32_t, sizeof(uint32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<uint32_t2x4 >::type> : integral_constant<uint32_t, sizeof(uint32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const uint32_t2x4 >::type> : integral_constant<uint32_t, sizeof(uint32_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<uint32_t2x3 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<uint32_t2x3 > : integral_constant<uint32_t, sizeof(uint32_t) > {}; template<> struct alignment_of<const uint32_t2x3 > : integral_constant<uint32_t, sizeof(uint32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<uint32_t2x3 >::type> : integral_constant<uint32_t, sizeof(uint32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const uint32_t2x3 >::type> : integral_constant<uint32_t, sizeof(uint32_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<uint32_t2x2 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<uint32_t2x2 > : integral_constant<uint32_t, sizeof(uint32_t) > {}; template<> struct alignment_of<const uint32_t2x2 > : integral_constant<uint32_t, sizeof(uint32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<uint32_t2x2 >::type> : integral_constant<uint32_t, sizeof(uint32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const uint32_t2x2 >::type> : integral_constant<uint32_t, sizeof(uint32_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<uint32_t3 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<uint32_t3 > : integral_constant<uint32_t, sizeof(uint32_t) > {}; template<> struct alignment_of<const uint32_t3 > : integral_constant<uint32_t, sizeof(uint32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<uint32_t3 >::type> : integral_constant<uint32_t, sizeof(uint32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const uint32_t3 >::type> : integral_constant<uint32_t, sizeof(uint32_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<uint32_t3x4 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<uint32_t3x4 > : integral_constant<uint32_t, sizeof(uint32_t) > {}; template<> struct alignment_of<const uint32_t3x4 > : integral_constant<uint32_t, sizeof(uint32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<uint32_t3x4 >::type> : integral_constant<uint32_t, sizeof(uint32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const uint32_t3x4 >::type> : integral_constant<uint32_t, sizeof(uint32_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<uint32_t3x3 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<uint32_t3x3 > : integral_constant<uint32_t, sizeof(uint32_t) > {}; template<> struct alignment_of<const uint32_t3x3 > : integral_constant<uint32_t, sizeof(uint32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<uint32_t3x3 >::type> : integral_constant<uint32_t, sizeof(uint32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const uint32_t3x3 >::type> : integral_constant<uint32_t, sizeof(uint32_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<uint32_t3x2 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<uint32_t3x2 > : integral_constant<uint32_t, sizeof(uint32_t) > {}; template<> struct alignment_of<const uint32_t3x2 > : integral_constant<uint32_t, sizeof(uint32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<uint32_t3x2 >::type> : integral_constant<uint32_t, sizeof(uint32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const uint32_t3x2 >::type> : integral_constant<uint32_t, sizeof(uint32_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<uint32_t4 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<uint32_t4 > : integral_constant<uint32_t, sizeof(uint32_t) > {}; template<> struct alignment_of<const uint32_t4 > : integral_constant<uint32_t, sizeof(uint32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<uint32_t4 >::type> : integral_constant<uint32_t, sizeof(uint32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const uint32_t4 >::type> : integral_constant<uint32_t, sizeof(uint32_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<uint32_t4x4 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<uint32_t4x4 > : integral_constant<uint32_t, sizeof(uint32_t) > {}; template<> struct alignment_of<const uint32_t4x4 > : integral_constant<uint32_t, sizeof(uint32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<uint32_t4x4 >::type> : integral_constant<uint32_t, sizeof(uint32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const uint32_t4x4 >::type> : integral_constant<uint32_t, sizeof(uint32_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<uint32_t4x3 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<uint32_t4x3 > : integral_constant<uint32_t, sizeof(uint32_t) > {}; template<> struct alignment_of<const uint32_t4x3 > : integral_constant<uint32_t, sizeof(uint32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<uint32_t4x3 >::type> : integral_constant<uint32_t, sizeof(uint32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const uint32_t4x3 >::type> : integral_constant<uint32_t, sizeof(uint32_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<uint32_t4x2 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<uint32_t4x2 > : integral_constant<uint32_t, sizeof(uint32_t) > {}; template<> struct alignment_of<const uint32_t4x2 > : integral_constant<uint32_t, sizeof(uint32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<uint32_t4x2 >::type> : integral_constant<uint32_t, sizeof(uint32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const uint32_t4x2 >::type> : integral_constant<uint32_t, sizeof(uint32_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<uint64_t > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<uint64_t > : integral_constant<uint32_t, sizeof(uint64_t) > {}; template<> struct alignment_of<const uint64_t > : integral_constant<uint32_t, sizeof(uint64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<uint64_t >::type> : integral_constant<uint32_t, sizeof(uint64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const uint64_t >::type> : integral_constant<uint32_t, sizeof(uint64_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<uint64_t1 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<uint64_t1 > : integral_constant<uint32_t, sizeof(uint64_t) > {}; template<> struct alignment_of<const uint64_t1 > : integral_constant<uint32_t, sizeof(uint64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<uint64_t1 >::type> : integral_constant<uint32_t, sizeof(uint64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const uint64_t1 >::type> : integral_constant<uint32_t, sizeof(uint64_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<uint64_t2 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<uint64_t2 > : integral_constant<uint32_t, sizeof(uint64_t) > {}; template<> struct alignment_of<const uint64_t2 > : integral_constant<uint32_t, sizeof(uint64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<uint64_t2 >::type> : integral_constant<uint32_t, sizeof(uint64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const uint64_t2 >::type> : integral_constant<uint32_t, sizeof(uint64_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<uint64_t2x4 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<uint64_t2x4 > : integral_constant<uint32_t, sizeof(uint64_t) > {}; template<> struct alignment_of<const uint64_t2x4 > : integral_constant<uint32_t, sizeof(uint64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<uint64_t2x4 >::type> : integral_constant<uint32_t, sizeof(uint64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const uint64_t2x4 >::type> : integral_constant<uint32_t, sizeof(uint64_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<uint64_t2x3 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<uint64_t2x3 > : integral_constant<uint32_t, sizeof(uint64_t) > {}; template<> struct alignment_of<const uint64_t2x3 > : integral_constant<uint32_t, sizeof(uint64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<uint64_t2x3 >::type> : integral_constant<uint32_t, sizeof(uint64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const uint64_t2x3 >::type> : integral_constant<uint32_t, sizeof(uint64_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<uint64_t2x2 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<uint64_t2x2 > : integral_constant<uint32_t, sizeof(uint64_t) > {}; template<> struct alignment_of<const uint64_t2x2 > : integral_constant<uint32_t, sizeof(uint64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<uint64_t2x2 >::type> : integral_constant<uint32_t, sizeof(uint64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const uint64_t2x2 >::type> : integral_constant<uint32_t, sizeof(uint64_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<uint64_t3 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<uint64_t3 > : integral_constant<uint32_t, sizeof(uint64_t) > {}; template<> struct alignment_of<const uint64_t3 > : integral_constant<uint32_t, sizeof(uint64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<uint64_t3 >::type> : integral_constant<uint32_t, sizeof(uint64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const uint64_t3 >::type> : integral_constant<uint32_t, sizeof(uint64_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<uint64_t3x4 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<uint64_t3x4 > : integral_constant<uint32_t, sizeof(uint64_t) > {}; template<> struct alignment_of<const uint64_t3x4 > : integral_constant<uint32_t, sizeof(uint64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<uint64_t3x4 >::type> : integral_constant<uint32_t, sizeof(uint64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const uint64_t3x4 >::type> : integral_constant<uint32_t, sizeof(uint64_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<uint64_t3x3 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<uint64_t3x3 > : integral_constant<uint32_t, sizeof(uint64_t) > {}; template<> struct alignment_of<const uint64_t3x3 > : integral_constant<uint32_t, sizeof(uint64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<uint64_t3x3 >::type> : integral_constant<uint32_t, sizeof(uint64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const uint64_t3x3 >::type> : integral_constant<uint32_t, sizeof(uint64_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<uint64_t3x2 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<uint64_t3x2 > : integral_constant<uint32_t, sizeof(uint64_t) > {}; template<> struct alignment_of<const uint64_t3x2 > : integral_constant<uint32_t, sizeof(uint64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<uint64_t3x2 >::type> : integral_constant<uint32_t, sizeof(uint64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const uint64_t3x2 >::type> : integral_constant<uint32_t, sizeof(uint64_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<uint64_t4 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<uint64_t4 > : integral_constant<uint32_t, sizeof(uint64_t) > {}; template<> struct alignment_of<const uint64_t4 > : integral_constant<uint32_t, sizeof(uint64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<uint64_t4 >::type> : integral_constant<uint32_t, sizeof(uint64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const uint64_t4 >::type> : integral_constant<uint32_t, sizeof(uint64_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<uint64_t4x4 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<uint64_t4x4 > : integral_constant<uint32_t, sizeof(uint64_t) > {}; template<> struct alignment_of<const uint64_t4x4 > : integral_constant<uint32_t, sizeof(uint64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<uint64_t4x4 >::type> : integral_constant<uint32_t, sizeof(uint64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const uint64_t4x4 >::type> : integral_constant<uint32_t, sizeof(uint64_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<uint64_t4x3 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<uint64_t4x3 > : integral_constant<uint32_t, sizeof(uint64_t) > {}; template<> struct alignment_of<const uint64_t4x3 > : integral_constant<uint32_t, sizeof(uint64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<uint64_t4x3 >::type> : integral_constant<uint32_t, sizeof(uint64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const uint64_t4x3 >::type> : integral_constant<uint32_t, sizeof(uint64_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<uint64_t4x2 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<uint64_t4x2 > : integral_constant<uint32_t, sizeof(uint64_t) > {}; template<> struct alignment_of<const uint64_t4x2 > : integral_constant<uint32_t, sizeof(uint64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<uint64_t4x2 >::type> : integral_constant<uint32_t, sizeof(uint64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const uint64_t4x2 >::type> : integral_constant<uint32_t, sizeof(uint64_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<bool > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<bool > : integral_constant<uint32_t, sizeof(bool) > {}; template<> struct alignment_of<const bool > : integral_constant<uint32_t, sizeof(bool) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<bool >::type> : integral_constant<uint32_t, sizeof(bool) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const bool >::type> : integral_constant<uint32_t, sizeof(bool) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<bool1 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<bool1 > : integral_constant<uint32_t, sizeof(bool) > {}; template<> struct alignment_of<const bool1 > : integral_constant<uint32_t, sizeof(bool) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<bool1 >::type> : integral_constant<uint32_t, sizeof(bool) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const bool1 >::type> : integral_constant<uint32_t, sizeof(bool) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<bool2 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<bool2 > : integral_constant<uint32_t, sizeof(bool) > {}; template<> struct alignment_of<const bool2 > : integral_constant<uint32_t, sizeof(bool) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<bool2 >::type> : integral_constant<uint32_t, sizeof(bool) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const bool2 >::type> : integral_constant<uint32_t, sizeof(bool) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<bool2x4 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<bool2x4 > : integral_constant<uint32_t, sizeof(bool) > {}; template<> struct alignment_of<const bool2x4 > : integral_constant<uint32_t, sizeof(bool) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<bool2x4 >::type> : integral_constant<uint32_t, sizeof(bool) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const bool2x4 >::type> : integral_constant<uint32_t, sizeof(bool) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<bool2x3 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<bool2x3 > : integral_constant<uint32_t, sizeof(bool) > {}; template<> struct alignment_of<const bool2x3 > : integral_constant<uint32_t, sizeof(bool) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<bool2x3 >::type> : integral_constant<uint32_t, sizeof(bool) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const bool2x3 >::type> : integral_constant<uint32_t, sizeof(bool) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<bool2x2 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<bool2x2 > : integral_constant<uint32_t, sizeof(bool) > {}; template<> struct alignment_of<const bool2x2 > : integral_constant<uint32_t, sizeof(bool) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<bool2x2 >::type> : integral_constant<uint32_t, sizeof(bool) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const bool2x2 >::type> : integral_constant<uint32_t, sizeof(bool) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<bool3 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<bool3 > : integral_constant<uint32_t, sizeof(bool) > {}; template<> struct alignment_of<const bool3 > : integral_constant<uint32_t, sizeof(bool) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<bool3 >::type> : integral_constant<uint32_t, sizeof(bool) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const bool3 >::type> : integral_constant<uint32_t, sizeof(bool) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<bool3x4 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<bool3x4 > : integral_constant<uint32_t, sizeof(bool) > {}; template<> struct alignment_of<const bool3x4 > : integral_constant<uint32_t, sizeof(bool) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<bool3x4 >::type> : integral_constant<uint32_t, sizeof(bool) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const bool3x4 >::type> : integral_constant<uint32_t, sizeof(bool) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<bool3x3 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<bool3x3 > : integral_constant<uint32_t, sizeof(bool) > {}; template<> struct alignment_of<const bool3x3 > : integral_constant<uint32_t, sizeof(bool) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<bool3x3 >::type> : integral_constant<uint32_t, sizeof(bool) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const bool3x3 >::type> : integral_constant<uint32_t, sizeof(bool) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<bool3x2 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<bool3x2 > : integral_constant<uint32_t, sizeof(bool) > {}; template<> struct alignment_of<const bool3x2 > : integral_constant<uint32_t, sizeof(bool) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<bool3x2 >::type> : integral_constant<uint32_t, sizeof(bool) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const bool3x2 >::type> : integral_constant<uint32_t, sizeof(bool) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<bool4 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<bool4 > : integral_constant<uint32_t, sizeof(bool) > {}; template<> struct alignment_of<const bool4 > : integral_constant<uint32_t, sizeof(bool) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<bool4 >::type> : integral_constant<uint32_t, sizeof(bool) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const bool4 >::type> : integral_constant<uint32_t, sizeof(bool) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<bool4x4 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<bool4x4 > : integral_constant<uint32_t, sizeof(bool) > {}; template<> struct alignment_of<const bool4x4 > : integral_constant<uint32_t, sizeof(bool) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<bool4x4 >::type> : integral_constant<uint32_t, sizeof(bool) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const bool4x4 >::type> : integral_constant<uint32_t, sizeof(bool) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<bool4x3 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<bool4x3 > : integral_constant<uint32_t, sizeof(bool) > {}; template<> struct alignment_of<const bool4x3 > : integral_constant<uint32_t, sizeof(bool) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<bool4x3 >::type> : integral_constant<uint32_t, sizeof(bool) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const bool4x3 >::type> : integral_constant<uint32_t, sizeof(bool) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<bool4x2 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<bool4x2 > : integral_constant<uint32_t, sizeof(bool) > {}; template<> struct alignment_of<const bool4x2 > : integral_constant<uint32_t, sizeof(bool) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<bool4x2 >::type> : integral_constant<uint32_t, sizeof(bool) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const bool4x2 >::type> : integral_constant<uint32_t, sizeof(bool) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<float16_t > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<float16_t > : integral_constant<uint32_t, sizeof(float16_t) > {}; template<> struct alignment_of<const float16_t > : integral_constant<uint32_t, sizeof(float16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<float16_t >::type> : integral_constant<uint32_t, sizeof(float16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const float16_t >::type> : integral_constant<uint32_t, sizeof(float16_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<float16_t1 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<float16_t1 > : integral_constant<uint32_t, sizeof(float16_t) > {}; template<> struct alignment_of<const float16_t1 > : integral_constant<uint32_t, sizeof(float16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<float16_t1 >::type> : integral_constant<uint32_t, sizeof(float16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const float16_t1 >::type> : integral_constant<uint32_t, sizeof(float16_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<float16_t2 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<float16_t2 > : integral_constant<uint32_t, sizeof(float16_t) > {}; template<> struct alignment_of<const float16_t2 > : integral_constant<uint32_t, sizeof(float16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<float16_t2 >::type> : integral_constant<uint32_t, sizeof(float16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const float16_t2 >::type> : integral_constant<uint32_t, sizeof(float16_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<float16_t2x4 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<float16_t2x4 > : integral_constant<uint32_t, sizeof(float16_t) > {}; template<> struct alignment_of<const float16_t2x4 > : integral_constant<uint32_t, sizeof(float16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<float16_t2x4 >::type> : integral_constant<uint32_t, sizeof(float16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const float16_t2x4 >::type> : integral_constant<uint32_t, sizeof(float16_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<float16_t2x3 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<float16_t2x3 > : integral_constant<uint32_t, sizeof(float16_t) > {}; template<> struct alignment_of<const float16_t2x3 > : integral_constant<uint32_t, sizeof(float16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<float16_t2x3 >::type> : integral_constant<uint32_t, sizeof(float16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const float16_t2x3 >::type> : integral_constant<uint32_t, sizeof(float16_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<float16_t2x2 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<float16_t2x2 > : integral_constant<uint32_t, sizeof(float16_t) > {}; template<> struct alignment_of<const float16_t2x2 > : integral_constant<uint32_t, sizeof(float16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<float16_t2x2 >::type> : integral_constant<uint32_t, sizeof(float16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const float16_t2x2 >::type> : integral_constant<uint32_t, sizeof(float16_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<float16_t3 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<float16_t3 > : integral_constant<uint32_t, sizeof(float16_t) > {}; template<> struct alignment_of<const float16_t3 > : integral_constant<uint32_t, sizeof(float16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<float16_t3 >::type> : integral_constant<uint32_t, sizeof(float16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const float16_t3 >::type> : integral_constant<uint32_t, sizeof(float16_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<float16_t3x4 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<float16_t3x4 > : integral_constant<uint32_t, sizeof(float16_t) > {}; template<> struct alignment_of<const float16_t3x4 > : integral_constant<uint32_t, sizeof(float16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<float16_t3x4 >::type> : integral_constant<uint32_t, sizeof(float16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const float16_t3x4 >::type> : integral_constant<uint32_t, sizeof(float16_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<float16_t3x3 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<float16_t3x3 > : integral_constant<uint32_t, sizeof(float16_t) > {}; template<> struct alignment_of<const float16_t3x3 > : integral_constant<uint32_t, sizeof(float16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<float16_t3x3 >::type> : integral_constant<uint32_t, sizeof(float16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const float16_t3x3 >::type> : integral_constant<uint32_t, sizeof(float16_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<float16_t3x2 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<float16_t3x2 > : integral_constant<uint32_t, sizeof(float16_t) > {}; template<> struct alignment_of<const float16_t3x2 > : integral_constant<uint32_t, sizeof(float16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<float16_t3x2 >::type> : integral_constant<uint32_t, sizeof(float16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const float16_t3x2 >::type> : integral_constant<uint32_t, sizeof(float16_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<float16_t4 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<float16_t4 > : integral_constant<uint32_t, sizeof(float16_t) > {}; template<> struct alignment_of<const float16_t4 > : integral_constant<uint32_t, sizeof(float16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<float16_t4 >::type> : integral_constant<uint32_t, sizeof(float16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const float16_t4 >::type> : integral_constant<uint32_t, sizeof(float16_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<float16_t4x4 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<float16_t4x4 > : integral_constant<uint32_t, sizeof(float16_t) > {}; template<> struct alignment_of<const float16_t4x4 > : integral_constant<uint32_t, sizeof(float16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<float16_t4x4 >::type> : integral_constant<uint32_t, sizeof(float16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const float16_t4x4 >::type> : integral_constant<uint32_t, sizeof(float16_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<float16_t4x3 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<float16_t4x3 > : integral_constant<uint32_t, sizeof(float16_t) > {}; template<> struct alignment_of<const float16_t4x3 > : integral_constant<uint32_t, sizeof(float16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<float16_t4x3 >::type> : integral_constant<uint32_t, sizeof(float16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const float16_t4x3 >::type> : integral_constant<uint32_t, sizeof(float16_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<float16_t4x2 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<float16_t4x2 > : integral_constant<uint32_t, sizeof(float16_t) > {}; template<> struct alignment_of<const float16_t4x2 > : integral_constant<uint32_t, sizeof(float16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<float16_t4x2 >::type> : integral_constant<uint32_t, sizeof(float16_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const float16_t4x2 >::type> : integral_constant<uint32_t, sizeof(float16_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<float32_t > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<float32_t > : integral_constant<uint32_t, sizeof(float32_t) > {}; template<> struct alignment_of<const float32_t > : integral_constant<uint32_t, sizeof(float32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<float32_t >::type> : integral_constant<uint32_t, sizeof(float32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const float32_t >::type> : integral_constant<uint32_t, sizeof(float32_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<float32_t1 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<float32_t1 > : integral_constant<uint32_t, sizeof(float32_t) > {}; template<> struct alignment_of<const float32_t1 > : integral_constant<uint32_t, sizeof(float32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<float32_t1 >::type> : integral_constant<uint32_t, sizeof(float32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const float32_t1 >::type> : integral_constant<uint32_t, sizeof(float32_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<float32_t2 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<float32_t2 > : integral_constant<uint32_t, sizeof(float32_t) > {}; template<> struct alignment_of<const float32_t2 > : integral_constant<uint32_t, sizeof(float32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<float32_t2 >::type> : integral_constant<uint32_t, sizeof(float32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const float32_t2 >::type> : integral_constant<uint32_t, sizeof(float32_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<float32_t2x4 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<float32_t2x4 > : integral_constant<uint32_t, sizeof(float32_t) > {}; template<> struct alignment_of<const float32_t2x4 > : integral_constant<uint32_t, sizeof(float32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<float32_t2x4 >::type> : integral_constant<uint32_t, sizeof(float32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const float32_t2x4 >::type> : integral_constant<uint32_t, sizeof(float32_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<float32_t2x3 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<float32_t2x3 > : integral_constant<uint32_t, sizeof(float32_t) > {}; template<> struct alignment_of<const float32_t2x3 > : integral_constant<uint32_t, sizeof(float32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<float32_t2x3 >::type> : integral_constant<uint32_t, sizeof(float32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const float32_t2x3 >::type> : integral_constant<uint32_t, sizeof(float32_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<float32_t2x2 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<float32_t2x2 > : integral_constant<uint32_t, sizeof(float32_t) > {}; template<> struct alignment_of<const float32_t2x2 > : integral_constant<uint32_t, sizeof(float32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<float32_t2x2 >::type> : integral_constant<uint32_t, sizeof(float32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const float32_t2x2 >::type> : integral_constant<uint32_t, sizeof(float32_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<float32_t3 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<float32_t3 > : integral_constant<uint32_t, sizeof(float32_t) > {}; template<> struct alignment_of<const float32_t3 > : integral_constant<uint32_t, sizeof(float32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<float32_t3 >::type> : integral_constant<uint32_t, sizeof(float32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const float32_t3 >::type> : integral_constant<uint32_t, sizeof(float32_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<float32_t3x4 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<float32_t3x4 > : integral_constant<uint32_t, sizeof(float32_t) > {}; template<> struct alignment_of<const float32_t3x4 > : integral_constant<uint32_t, sizeof(float32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<float32_t3x4 >::type> : integral_constant<uint32_t, sizeof(float32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const float32_t3x4 >::type> : integral_constant<uint32_t, sizeof(float32_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<float32_t3x3 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<float32_t3x3 > : integral_constant<uint32_t, sizeof(float32_t) > {}; template<> struct alignment_of<const float32_t3x3 > : integral_constant<uint32_t, sizeof(float32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<float32_t3x3 >::type> : integral_constant<uint32_t, sizeof(float32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const float32_t3x3 >::type> : integral_constant<uint32_t, sizeof(float32_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<float32_t3x2 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<float32_t3x2 > : integral_constant<uint32_t, sizeof(float32_t) > {}; template<> struct alignment_of<const float32_t3x2 > : integral_constant<uint32_t, sizeof(float32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<float32_t3x2 >::type> : integral_constant<uint32_t, sizeof(float32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const float32_t3x2 >::type> : integral_constant<uint32_t, sizeof(float32_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<float32_t4 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<float32_t4 > : integral_constant<uint32_t, sizeof(float32_t) > {}; template<> struct alignment_of<const float32_t4 > : integral_constant<uint32_t, sizeof(float32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<float32_t4 >::type> : integral_constant<uint32_t, sizeof(float32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const float32_t4 >::type> : integral_constant<uint32_t, sizeof(float32_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<float32_t4x4 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<float32_t4x4 > : integral_constant<uint32_t, sizeof(float32_t) > {}; template<> struct alignment_of<const float32_t4x4 > : integral_constant<uint32_t, sizeof(float32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<float32_t4x4 >::type> : integral_constant<uint32_t, sizeof(float32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const float32_t4x4 >::type> : integral_constant<uint32_t, sizeof(float32_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<float32_t4x3 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<float32_t4x3 > : integral_constant<uint32_t, sizeof(float32_t) > {}; template<> struct alignment_of<const float32_t4x3 > : integral_constant<uint32_t, sizeof(float32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<float32_t4x3 >::type> : integral_constant<uint32_t, sizeof(float32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const float32_t4x3 >::type> : integral_constant<uint32_t, sizeof(float32_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<float32_t4x2 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<float32_t4x2 > : integral_constant<uint32_t, sizeof(float32_t) > {}; template<> struct alignment_of<const float32_t4x2 > : integral_constant<uint32_t, sizeof(float32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<float32_t4x2 >::type> : integral_constant<uint32_t, sizeof(float32_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const float32_t4x2 >::type> : integral_constant<uint32_t, sizeof(float32_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<float64_t > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<float64_t > : integral_constant<uint32_t, sizeof(float64_t) > {}; template<> struct alignment_of<const float64_t > : integral_constant<uint32_t, sizeof(float64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<float64_t >::type> : integral_constant<uint32_t, sizeof(float64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const float64_t >::type> : integral_constant<uint32_t, sizeof(float64_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<float64_t1 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<float64_t1 > : integral_constant<uint32_t, sizeof(float64_t) > {}; template<> struct alignment_of<const float64_t1 > : integral_constant<uint32_t, sizeof(float64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<float64_t1 >::type> : integral_constant<uint32_t, sizeof(float64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const float64_t1 >::type> : integral_constant<uint32_t, sizeof(float64_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<float64_t2 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<float64_t2 > : integral_constant<uint32_t, sizeof(float64_t) > {}; template<> struct alignment_of<const float64_t2 > : integral_constant<uint32_t, sizeof(float64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<float64_t2 >::type> : integral_constant<uint32_t, sizeof(float64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const float64_t2 >::type> : integral_constant<uint32_t, sizeof(float64_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<float64_t2x4 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<float64_t2x4 > : integral_constant<uint32_t, sizeof(float64_t) > {}; template<> struct alignment_of<const float64_t2x4 > : integral_constant<uint32_t, sizeof(float64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<float64_t2x4 >::type> : integral_constant<uint32_t, sizeof(float64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const float64_t2x4 >::type> : integral_constant<uint32_t, sizeof(float64_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<float64_t2x3 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<float64_t2x3 > : integral_constant<uint32_t, sizeof(float64_t) > {}; template<> struct alignment_of<const float64_t2x3 > : integral_constant<uint32_t, sizeof(float64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<float64_t2x3 >::type> : integral_constant<uint32_t, sizeof(float64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const float64_t2x3 >::type> : integral_constant<uint32_t, sizeof(float64_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<float64_t2x2 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<float64_t2x2 > : integral_constant<uint32_t, sizeof(float64_t) > {}; template<> struct alignment_of<const float64_t2x2 > : integral_constant<uint32_t, sizeof(float64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<float64_t2x2 >::type> : integral_constant<uint32_t, sizeof(float64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const float64_t2x2 >::type> : integral_constant<uint32_t, sizeof(float64_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<float64_t3 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<float64_t3 > : integral_constant<uint32_t, sizeof(float64_t) > {}; template<> struct alignment_of<const float64_t3 > : integral_constant<uint32_t, sizeof(float64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<float64_t3 >::type> : integral_constant<uint32_t, sizeof(float64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const float64_t3 >::type> : integral_constant<uint32_t, sizeof(float64_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<float64_t3x4 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<float64_t3x4 > : integral_constant<uint32_t, sizeof(float64_t) > {}; template<> struct alignment_of<const float64_t3x4 > : integral_constant<uint32_t, sizeof(float64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<float64_t3x4 >::type> : integral_constant<uint32_t, sizeof(float64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const float64_t3x4 >::type> : integral_constant<uint32_t, sizeof(float64_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<float64_t3x3 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<float64_t3x3 > : integral_constant<uint32_t, sizeof(float64_t) > {}; template<> struct alignment_of<const float64_t3x3 > : integral_constant<uint32_t, sizeof(float64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<float64_t3x3 >::type> : integral_constant<uint32_t, sizeof(float64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const float64_t3x3 >::type> : integral_constant<uint32_t, sizeof(float64_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<float64_t3x2 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<float64_t3x2 > : integral_constant<uint32_t, sizeof(float64_t) > {}; template<> struct alignment_of<const float64_t3x2 > : integral_constant<uint32_t, sizeof(float64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<float64_t3x2 >::type> : integral_constant<uint32_t, sizeof(float64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const float64_t3x2 >::type> : integral_constant<uint32_t, sizeof(float64_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<float64_t4 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<float64_t4 > : integral_constant<uint32_t, sizeof(float64_t) > {}; template<> struct alignment_of<const float64_t4 > : integral_constant<uint32_t, sizeof(float64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<float64_t4 >::type> : integral_constant<uint32_t, sizeof(float64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const float64_t4 >::type> : integral_constant<uint32_t, sizeof(float64_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<float64_t4x4 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<float64_t4x4 > : integral_constant<uint32_t, sizeof(float64_t) > {}; template<> struct alignment_of<const float64_t4x4 > : integral_constant<uint32_t, sizeof(float64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<float64_t4x4 >::type> : integral_constant<uint32_t, sizeof(float64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const float64_t4x4 >::type> : integral_constant<uint32_t, sizeof(float64_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<float64_t4x3 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<float64_t4x3 > : integral_constant<uint32_t, sizeof(float64_t) > {}; template<> struct alignment_of<const float64_t4x3 > : integral_constant<uint32_t, sizeof(float64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<float64_t4x3 >::type> : integral_constant<uint32_t, sizeof(float64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const float64_t4x3 >::type> : integral_constant<uint32_t, sizeof(float64_t) > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<float64_t4x2 > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<float64_t4x2 > : integral_constant<uint32_t, sizeof(float64_t) > {}; template<> struct alignment_of<const float64_t4x2 > : integral_constant<uint32_t, sizeof(float64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<float64_t4x2 >::type> : integral_constant<uint32_t, sizeof(float64_t) > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const float64_t4x2 >::type> : integral_constant<uint32_t, sizeof(float64_t) > {}; }} #line 5 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/vector_utils/vector_traits.hlsl" namespace nbl { namespace hlsl { // The whole purpose of this file is to enable the creation of partial specializations of the vector_traits for // custom types without introducing circular dependencies. template<typename T> struct vector_traits { using scalar_type = T; const static uint32_t Dimension = 1u; const static bool IsVector = false; }; // i choose to implement it this way because of this DXC bug: https://github.com/microsoft/DirectXShaderCom0piler/issues/7007 #line 31 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/vector_utils/vector_traits.hlsl" template<typename T> struct vector_traits<vector<T, 1> >{ using scalar_type = T; const static uint32_t Dimension = 1; const static bool IsVector = true;}; template<typename T> struct vector_traits<vector<T, 2> >{ using scalar_type = T; const static uint32_t Dimension = 2; const static bool IsVector = true;}; template<typename T> struct vector_traits<vector<T, 3> >{ using scalar_type = T; const static uint32_t Dimension = 3; const static bool IsVector = true;}; template<typename T> struct vector_traits<vector<T, 4> >{ using scalar_type = T; const static uint32_t Dimension = 4; const static bool IsVector = true;}; } } #line 6 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/array_accessors.hlsl" namespace nbl { namespace hlsl { template<typename ArrayType, typename ComponentType, typename I = uint32_t> struct array_get { ComponentType operator()(const in ArrayType arr, const I ix) { return arr[ix]; } }; template<typename ArrayType, typename ComponentType, typename I = uint32_t> struct array_set { void operator()([[vk::ext_reference]] inout ArrayType arr, I index, ComponentType val) { arr[index] = val; } }; } } #line 7 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/matrix_utils/matrix_traits.hlsl" namespace nbl { namespace hlsl { template<typename T> struct matrix_traits { using scalar_type = T; using row_type = void; using transposed_type = void; const static uint32_t RowCount = 1; const static uint32_t ColumnCount = 1; const static bool Square = false; const static bool IsMatrix = false; }; // i choose to implement it this way because of this DXC bug: https://github.com/microsoft/DirectXShaderCompiler/issues/7007 #line 38 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/matrix_utils/matrix_traits.hlsl" template<typename T> struct matrix_traits<matrix<T, 1, 2> > { using scalar_type = T; using row_type = vector<T, 2>; using transposed_type = matrix<T, 2, 1>; const static uint32_t RowCount = 1; const static uint32_t ColumnCount = 2; const static bool Square = RowCount == ColumnCount; const static bool IsMatrix = true; }; template<typename T> struct matrix_traits<matrix<T, 1, 3> > { using scalar_type = T; using row_type = vector<T, 3>; using transposed_type = matrix<T, 3, 1>; const static uint32_t RowCount = 1; const static uint32_t ColumnCount = 3; const static bool Square = RowCount == ColumnCount; const static bool IsMatrix = true; }; template<typename T> struct matrix_traits<matrix<T, 1, 4> > { using scalar_type = T; using row_type = vector<T, 4>; using transposed_type = matrix<T, 4, 1>; const static uint32_t RowCount = 1; const static uint32_t ColumnCount = 4; const static bool Square = RowCount == ColumnCount; const static bool IsMatrix = true; }; template<typename T> struct matrix_traits<matrix<T, 2, 1> > { using scalar_type = T; using row_type = vector<T, 1>; using transposed_type = matrix<T, 1, 2>; const static uint32_t RowCount = 2; const static uint32_t ColumnCount = 1; const static bool Square = RowCount == ColumnCount; const static bool IsMatrix = true; }; template<typename T> struct matrix_traits<matrix<T, 2, 2> > { using scalar_type = T; using row_type = vector<T, 2>; using transposed_type = matrix<T, 2, 2>; const static uint32_t RowCount = 2; const static uint32_t ColumnCount = 2; const static bool Square = RowCount == ColumnCount; const static bool IsMatrix = true; }; template<typename T> struct matrix_traits<matrix<T, 2, 3> > { using scalar_type = T; using row_type = vector<T, 3>; using transposed_type = matrix<T, 3, 2>; const static uint32_t RowCount = 2; const static uint32_t ColumnCount = 3; const static bool Square = RowCount == ColumnCount; const static bool IsMatrix = true; }; template<typename T> struct matrix_traits<matrix<T, 2, 4> > { using scalar_type = T; using row_type = vector<T, 4>; using transposed_type = matrix<T, 4, 2>; const static uint32_t RowCount = 2; const static uint32_t ColumnCount = 4; const static bool Square = RowCount == ColumnCount; const static bool IsMatrix = true; }; template<typename T> struct matrix_traits<matrix<T, 3, 1> > { using scalar_type = T; using row_type = vector<T, 1>; using transposed_type = matrix<T, 1, 3>; const static uint32_t RowCount = 3; const static uint32_t ColumnCount = 1; const static bool Square = RowCount == ColumnCount; const static bool IsMatrix = true; }; template<typename T> struct matrix_traits<matrix<T, 3, 2> > { using scalar_type = T; using row_type = vector<T, 2>; using transposed_type = matrix<T, 2, 3>; const static uint32_t RowCount = 3; const static uint32_t ColumnCount = 2; const static bool Square = RowCount == ColumnCount; const static bool IsMatrix = true; }; template<typename T> struct matrix_traits<matrix<T, 3, 3> > { using scalar_type = T; using row_type = vector<T, 3>; using transposed_type = matrix<T, 3, 3>; const static uint32_t RowCount = 3; const static uint32_t ColumnCount = 3; const static bool Square = RowCount == ColumnCount; const static bool IsMatrix = true; }; template<typename T> struct matrix_traits<matrix<T, 3, 4> > { using scalar_type = T; using row_type = vector<T, 4>; using transposed_type = matrix<T, 4, 3>; const static uint32_t RowCount = 3; const static uint32_t ColumnCount = 4; const static bool Square = RowCount == ColumnCount; const static bool IsMatrix = true; }; template<typename T> struct matrix_traits<matrix<T, 4, 1> > { using scalar_type = T; using row_type = vector<T, 1>; using transposed_type = matrix<T, 1, 4>; const static uint32_t RowCount = 4; const static uint32_t ColumnCount = 1; const static bool Square = RowCount == ColumnCount; const static bool IsMatrix = true; }; template<typename T> struct matrix_traits<matrix<T, 4, 2> > { using scalar_type = T; using row_type = vector<T, 2>; using transposed_type = matrix<T, 2, 4>; const static uint32_t RowCount = 4; const static uint32_t ColumnCount = 2; const static bool Square = RowCount == ColumnCount; const static bool IsMatrix = true; }; template<typename T> struct matrix_traits<matrix<T, 4, 3> > { using scalar_type = T; using row_type = vector<T, 3>; using transposed_type = matrix<T, 3, 4>; const static uint32_t RowCount = 4; const static uint32_t ColumnCount = 3; const static bool Square = RowCount == ColumnCount; const static bool IsMatrix = true; }; template<typename T> struct matrix_traits<matrix<T, 4, 4> > { using scalar_type = T; using row_type = vector<T, 4>; using transposed_type = matrix<T, 4, 4>; const static uint32_t RowCount = 4; const static uint32_t ColumnCount = 4; const static bool Square = RowCount == ColumnCount; const static bool IsMatrix = true; }; // TODO: when this bug: https://github.com/microsoft/DirectXShaderCompiler/issues/7007 is fixed, uncomment and delete template specializations /*template<typename T, uint32_t N, uint32_t M> struct matrix_traits<matrix<T,N,M> > { using scalar_type = T; NBL_CONSTEXPR_STATIC_INLINE uint32_t RowCount = ROW_COUNT; NBL_CONSTEXPR_STATIC_INLINE uint32_t ColumnCount = COLUMN_COUNT; NBL_CONSTEXPR_STATIC_INLINE bool Square = RowCount == ColumnCount; }; */ } } #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts.hlsl" // Copyright (C) 2023-2024 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts/impl/base.hlsl" // Copyright (C) 2023-2024 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/utility.hlsl" // Copyright (C) 2024 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/type_traits.hlsl" // Copyright (C) 2022 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 11 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/utility.hlsl" // for now we only implement declval namespace nbl { namespace hlsl { template<typename T> const static bool always_true = true; #line 28 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/utility.hlsl" namespace experimental { template<class T> T declval() {} } } } #line 14 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts.hlsl" namespace nbl { namespace hlsl { namespace concepts { // common implementation juice #line 34 "C:/Users/Rynair/Desktop/Nabla/3rdparty/boost/superproject/libs/preprocessor/include/boost/preprocessor/tuple/rem.hpp" /* VC++8.0 cannot handle the variadic version of BOOST_PP_TUPLE_REM(size) */ #line 21 "C:/Users/Rynair/Desktop/Nabla/3rdparty/boost/superproject/libs/preprocessor/include/boost/preprocessor/seq/detail/is_empty.hpp" /* An empty seq is one that is just BOOST_PP_SEQ_NIL */ #line 31 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts.hlsl" // #line 34 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts.hlsl" // //! Now diverge #line 77 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts.hlsl" // for struct definitions, use instead of closing `>` on the primary template parameter list // NOTE: C++20 requires and C++11 enable_if have to be in different places! ITS OF UTTMOST IMPORTANCE YOUR REQUIRE CLAUSES ARE IDENTICAL FOR BOTH MACROS // put just after the closing `>` on the partial template specialization `template` declaration e.g. `template<typename U, typename V, typename T> NBL_PARTIAL_REQ_TOP(SomeCond<U>) // put just before closing `>` on the partial template specialization Type args, e.g. `MyStruct<U,V,T NBL_PARTIAL_REQ_BOT(SomeCond<U>)> // condition, use instead of the closing `>` of a function template // #line 92 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts.hlsl" // // #line 98 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts.hlsl" // // #line 107 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts.hlsl" // // #line 115 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts.hlsl" // TODO: counterparts of all the other concepts } } } #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/spirv_intrinsics/core.hlsl" // Copyright (C) 2023 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/spirv_intrinsics/output_structs.hlsl" // Copyright (C) 2023 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts/core.hlsl" // Copyright (C) 2024-2025 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts.hlsl" // Copyright (C) 2023-2024 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/type_traits.hlsl" // Copyright (C) 2022 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 12 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts/core.hlsl" namespace nbl { namespace hlsl { namespace concepts { template<typename T, typename U> const static bool same_as = is_same_v<T, U>; template<typename T> const static bool Integral = nbl::hlsl::is_integral_v<T>; template<typename T> const static bool SignedIntegral = nbl::hlsl::is_signed_v<T> && nbl::hlsl::is_integral_v<T>; template<typename T> const static bool UnsignedIntegral = !nbl::hlsl::is_signed_v<T> && ::nbl::hlsl::is_integral_v<T>; template<typename T> const static bool FloatingPoint = nbl::hlsl::is_floating_point_v<T>; template<typename T> const static bool Boolean = nbl::hlsl::is_same_v<T, bool> || (nbl::hlsl::is_vector_v<T> && nbl::hlsl::is_same_v<typename vector_traits<T>::scalar_type, bool>); template <typename T> const static bool Scalar = nbl::hlsl::is_scalar_v<T>; template<typename T> const static bool IntegralScalar = nbl::hlsl::is_integral_v<T> && nbl::hlsl::is_scalar_v<T>; template<typename T> const static bool SignedIntegralScalar = nbl::hlsl::is_signed_v<T> && nbl::hlsl::is_integral_v<T> && nbl::hlsl::is_scalar_v<T>; template<typename T> const static bool UnsignedIntegralScalar = !nbl::hlsl::is_signed_v<T> && ::nbl::hlsl::is_integral_v<T> && nbl::hlsl::is_scalar_v<T>; template<typename T> const static bool FloatingPointScalar = (nbl::hlsl::is_floating_point_v<T> && nbl::hlsl::is_scalar_v<T>); template<typename T> const static bool BooleanScalar = concepts::Boolean<T> && nbl::hlsl::is_scalar_v<T>; // TODO: implement when hlsl::is_base_of is done //#define NBL_CONCEPT_NAME DerivedFrom // ... // TODO: implement when hlsl::is_converible is done //#define NBL_CONCEPT_NAME ConvertibleTo // ... // TODO? //#define NBL_CONCEPT_NAME AssignableFrom // TODO? //template <typename T, typename U> //concept common_with = std::common_with<T, U>; namespace impl { template<typename T> struct is_emulating_floating_point_scalar { const static bool value = FloatingPointScalar<T>; }; template<typename T> struct is_emulating_integral_scalar { const static bool value = IntegralScalar<T>; }; } //! Floating point types are native floating point types or types that imitate native floating point types (for example emulated_float64_t) template<typename T> const static bool FloatingPointLikeScalar = impl::is_emulating_floating_point_scalar<T>::value; //! Integral-like types are native integral types or types that imitate native integral types (for example emulated_uint64_t) template<typename T> const static bool IntegralLikeScalar = impl::is_emulating_integral_scalar<T>::value; } } } #line 9 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/spirv_intrinsics/output_structs.hlsl" namespace nbl { namespace hlsl { namespace spirv { template<typename T ,typename __requires=void> struct AddCarryOutput; template<typename T ,typename __requires=void> struct SubBorrowOutput; template<typename T> struct AddCarryOutput<T ,::nbl::hlsl::enable_if_t<(concepts::UnsignedIntegral<T>),void> > { T result; T carry; }; template<typename T> struct SubBorrowOutput<T ,::nbl::hlsl::enable_if_t<(concepts::UnsignedIntegral<T>),void> > { T result; T borrow; }; } } } #line 1 "C:/Users/Rynair/Desktop/Nabla/3rdparty/dxc/dxc/external/SPIRV-Headers/include/spirv/unified1/spirv.hpp" // Copyright: 2014-2024 The Khronos Group Inc. // License: MIT // // MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS // KHRONOS STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS // SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT // https://www.khronos.org/registry/ // This header is automatically generated by the same tool that creates // the Binary Section of the SPIR-V specification. // Enumeration tokens for SPIR-V, in various styles: // C, C++, C++11, JSON, Lua, Python, C#, D, Beef // // - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL // - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL // - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL // - Lua will use tables, e.g.: spv.SourceLanguage.GLSL // - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] // - C# will use enum classes in the Specification class located in the "Spv" namespace, // e.g.: Spv.Specification.SourceLanguage.GLSL // - D will have tokens under the "spv" module, e.g: spv.SourceLanguage.GLSL // - Beef will use enum classes in the Specification class located in the "Spv" namespace, // e.g.: Spv.Specification.SourceLanguage.GLSL // // Some tokens act like mask values, which can be OR'd together, // while others are mutually exclusive. The mask-like ones have // "Mask" in their name, and a parallel enum that has the shift // amount (1 << x) for each corresponding enumerant. #line 34 "C:/Users/Rynair/Desktop/Nabla/3rdparty/dxc/dxc/external/SPIRV-Headers/include/spirv/unified1/spirv.hpp" namespace spv { typedef unsigned int Id; #line 41 "C:/Users/Rynair/Desktop/Nabla/3rdparty/dxc/dxc/external/SPIRV-Headers/include/spirv/unified1/spirv.hpp" static const unsigned int MagicNumber = 0x07230203; static const unsigned int Version = 0x00010600; static const unsigned int Revision = 1; static const unsigned int OpCodeMask = 0xffff; static const unsigned int WordCountShift = 16; enum SourceLanguage { SourceLanguageUnknown = 0, SourceLanguageESSL = 1, SourceLanguageGLSL = 2, SourceLanguageOpenCL_C = 3, SourceLanguageOpenCL_CPP = 4, SourceLanguageHLSL = 5, SourceLanguageCPP_for_OpenCL = 6, SourceLanguageSYCL = 7, SourceLanguageHERO_C = 8, SourceLanguageNZSL = 9, SourceLanguageWGSL = 10, SourceLanguageSlang = 11, SourceLanguageZig = 12, SourceLanguageRust = 13, SourceLanguageMax = 0x7fffffff, }; enum ExecutionModel { ExecutionModelVertex = 0, ExecutionModelTessellationControl = 1, ExecutionModelTessellationEvaluation = 2, ExecutionModelGeometry = 3, ExecutionModelFragment = 4, ExecutionModelGLCompute = 5, ExecutionModelKernel = 6, ExecutionModelTaskNV = 5267, ExecutionModelMeshNV = 5268, ExecutionModelRayGenerationKHR = 5313, ExecutionModelRayGenerationNV = 5313, ExecutionModelIntersectionKHR = 5314, ExecutionModelIntersectionNV = 5314, ExecutionModelAnyHitKHR = 5315, ExecutionModelAnyHitNV = 5315, ExecutionModelClosestHitKHR = 5316, ExecutionModelClosestHitNV = 5316, ExecutionModelMissKHR = 5317, ExecutionModelMissNV = 5317, ExecutionModelCallableKHR = 5318, ExecutionModelCallableNV = 5318, ExecutionModelTaskEXT = 5364, ExecutionModelMeshEXT = 5365, ExecutionModelMax = 0x7fffffff, }; enum AddressingModel { AddressingModelLogical = 0, AddressingModelPhysical32 = 1, AddressingModelPhysical64 = 2, AddressingModelPhysicalStorageBuffer64 = 5348, AddressingModelPhysicalStorageBuffer64EXT = 5348, AddressingModelMax = 0x7fffffff, }; enum MemoryModel { MemoryModelSimple = 0, MemoryModelGLSL450 = 1, MemoryModelOpenCL = 2, MemoryModelVulkan = 3, MemoryModelVulkanKHR = 3, MemoryModelMax = 0x7fffffff, }; enum ExecutionMode { ExecutionModeInvocations = 0, ExecutionModeSpacingEqual = 1, ExecutionModeSpacingFractionalEven = 2, ExecutionModeSpacingFractionalOdd = 3, ExecutionModeVertexOrderCw = 4, ExecutionModeVertexOrderCcw = 5, ExecutionModePixelCenterInteger = 6, ExecutionModeOriginUpperLeft = 7, ExecutionModeOriginLowerLeft = 8, ExecutionModeEarlyFragmentTests = 9, ExecutionModePointMode = 10, ExecutionModeXfb = 11, ExecutionModeDepthReplacing = 12, ExecutionModeDepthGreater = 14, ExecutionModeDepthLess = 15, ExecutionModeDepthUnchanged = 16, ExecutionModeLocalSize = 17, ExecutionModeLocalSizeHint = 18, ExecutionModeInputPoints = 19, ExecutionModeInputLines = 20, ExecutionModeInputLinesAdjacency = 21, ExecutionModeTriangles = 22, ExecutionModeInputTrianglesAdjacency = 23, ExecutionModeQuads = 24, ExecutionModeIsolines = 25, ExecutionModeOutputVertices = 26, ExecutionModeOutputPoints = 27, ExecutionModeOutputLineStrip = 28, ExecutionModeOutputTriangleStrip = 29, ExecutionModeVecTypeHint = 30, ExecutionModeContractionOff = 31, ExecutionModeInitializer = 33, ExecutionModeFinalizer = 34, ExecutionModeSubgroupSize = 35, ExecutionModeSubgroupsPerWorkgroup = 36, ExecutionModeSubgroupsPerWorkgroupId = 37, ExecutionModeLocalSizeId = 38, ExecutionModeLocalSizeHintId = 39, ExecutionModeNonCoherentColorAttachmentReadEXT = 4169, ExecutionModeNonCoherentDepthAttachmentReadEXT = 4170, ExecutionModeNonCoherentStencilAttachmentReadEXT = 4171, ExecutionModeSubgroupUniformControlFlowKHR = 4421, ExecutionModePostDepthCoverage = 4446, ExecutionModeDenormPreserve = 4459, ExecutionModeDenormFlushToZero = 4460, ExecutionModeSignedZeroInfNanPreserve = 4461, ExecutionModeRoundingModeRTE = 4462, ExecutionModeRoundingModeRTZ = 4463, ExecutionModeNonCoherentTileAttachmentReadQCOM = 4489, ExecutionModeTileShadingRateQCOM = 4490, ExecutionModeEarlyAndLateFragmentTestsAMD = 5017, ExecutionModeStencilRefReplacingEXT = 5027, ExecutionModeCoalescingAMDX = 5069, ExecutionModeIsApiEntryAMDX = 5070, ExecutionModeMaxNodeRecursionAMDX = 5071, ExecutionModeStaticNumWorkgroupsAMDX = 5072, ExecutionModeShaderIndexAMDX = 5073, ExecutionModeMaxNumWorkgroupsAMDX = 5077, ExecutionModeStencilRefUnchangedFrontAMD = 5079, ExecutionModeStencilRefGreaterFrontAMD = 5080, ExecutionModeStencilRefLessFrontAMD = 5081, ExecutionModeStencilRefUnchangedBackAMD = 5082, ExecutionModeStencilRefGreaterBackAMD = 5083, ExecutionModeStencilRefLessBackAMD = 5084, ExecutionModeQuadDerivativesKHR = 5088, ExecutionModeRequireFullQuadsKHR = 5089, ExecutionModeSharesInputWithAMDX = 5102, ExecutionModeOutputLinesEXT = 5269, ExecutionModeOutputLinesNV = 5269, ExecutionModeOutputPrimitivesEXT = 5270, ExecutionModeOutputPrimitivesNV = 5270, ExecutionModeDerivativeGroupQuadsKHR = 5289, ExecutionModeDerivativeGroupQuadsNV = 5289, ExecutionModeDerivativeGroupLinearKHR = 5290, ExecutionModeDerivativeGroupLinearNV = 5290, ExecutionModeOutputTrianglesEXT = 5298, ExecutionModeOutputTrianglesNV = 5298, ExecutionModePixelInterlockOrderedEXT = 5366, ExecutionModePixelInterlockUnorderedEXT = 5367, ExecutionModeSampleInterlockOrderedEXT = 5368, ExecutionModeSampleInterlockUnorderedEXT = 5369, ExecutionModeShadingRateInterlockOrderedEXT = 5370, ExecutionModeShadingRateInterlockUnorderedEXT = 5371, ExecutionModeSharedLocalMemorySizeINTEL = 5618, ExecutionModeRoundingModeRTPINTEL = 5620, ExecutionModeRoundingModeRTNINTEL = 5621, ExecutionModeFloatingPointModeALTINTEL = 5622, ExecutionModeFloatingPointModeIEEEINTEL = 5623, ExecutionModeMaxWorkgroupSizeINTEL = 5893, ExecutionModeMaxWorkDimINTEL = 5894, ExecutionModeNoGlobalOffsetINTEL = 5895, ExecutionModeNumSIMDWorkitemsINTEL = 5896, ExecutionModeSchedulerTargetFmaxMhzINTEL = 5903, ExecutionModeMaximallyReconvergesKHR = 6023, ExecutionModeFPFastMathDefault = 6028, ExecutionModeStreamingInterfaceINTEL = 6154, ExecutionModeRegisterMapInterfaceINTEL = 6160, ExecutionModeNamedBarrierCountINTEL = 6417, ExecutionModeMaximumRegistersINTEL = 6461, ExecutionModeMaximumRegistersIdINTEL = 6462, ExecutionModeNamedMaximumRegistersINTEL = 6463, ExecutionModeMax = 0x7fffffff, }; enum StorageClass { StorageClassUniformConstant = 0, StorageClassInput = 1, StorageClassUniform = 2, StorageClassOutput = 3, StorageClassWorkgroup = 4, StorageClassCrossWorkgroup = 5, StorageClassPrivate = 6, StorageClassFunction = 7, StorageClassGeneric = 8, StorageClassPushConstant = 9, StorageClassAtomicCounter = 10, StorageClassImage = 11, StorageClassStorageBuffer = 12, StorageClassTileImageEXT = 4172, StorageClassTileAttachmentQCOM = 4491, StorageClassNodePayloadAMDX = 5068, StorageClassCallableDataKHR = 5328, StorageClassCallableDataNV = 5328, StorageClassIncomingCallableDataKHR = 5329, StorageClassIncomingCallableDataNV = 5329, StorageClassRayPayloadKHR = 5338, StorageClassRayPayloadNV = 5338, StorageClassHitAttributeKHR = 5339, StorageClassHitAttributeNV = 5339, StorageClassIncomingRayPayloadKHR = 5342, StorageClassIncomingRayPayloadNV = 5342, StorageClassShaderRecordBufferKHR = 5343, StorageClassShaderRecordBufferNV = 5343, StorageClassPhysicalStorageBuffer = 5349, StorageClassPhysicalStorageBufferEXT = 5349, StorageClassHitObjectAttributeNV = 5385, StorageClassTaskPayloadWorkgroupEXT = 5402, StorageClassCodeSectionINTEL = 5605, StorageClassDeviceOnlyINTEL = 5936, StorageClassHostOnlyINTEL = 5937, StorageClassMax = 0x7fffffff, }; enum Dim { Dim1D = 0, Dim2D = 1, Dim3D = 2, DimCube = 3, DimRect = 4, DimBuffer = 5, DimSubpassData = 6, DimTileImageDataEXT = 4173, DimMax = 0x7fffffff, }; enum SamplerAddressingMode { SamplerAddressingModeNone = 0, SamplerAddressingModeClampToEdge = 1, SamplerAddressingModeClamp = 2, SamplerAddressingModeRepeat = 3, SamplerAddressingModeRepeatMirrored = 4, SamplerAddressingModeMax = 0x7fffffff, }; enum SamplerFilterMode { SamplerFilterModeNearest = 0, SamplerFilterModeLinear = 1, SamplerFilterModeMax = 0x7fffffff, }; enum ImageFormat { ImageFormatUnknown = 0, ImageFormatRgba32f = 1, ImageFormatRgba16f = 2, ImageFormatR32f = 3, ImageFormatRgba8 = 4, ImageFormatRgba8Snorm = 5, ImageFormatRg32f = 6, ImageFormatRg16f = 7, ImageFormatR11fG11fB10f = 8, ImageFormatR16f = 9, ImageFormatRgba16 = 10, ImageFormatRgb10A2 = 11, ImageFormatRg16 = 12, ImageFormatRg8 = 13, ImageFormatR16 = 14, ImageFormatR8 = 15, ImageFormatRgba16Snorm = 16, ImageFormatRg16Snorm = 17, ImageFormatRg8Snorm = 18, ImageFormatR16Snorm = 19, ImageFormatR8Snorm = 20, ImageFormatRgba32i = 21, ImageFormatRgba16i = 22, ImageFormatRgba8i = 23, ImageFormatR32i = 24, ImageFormatRg32i = 25, ImageFormatRg16i = 26, ImageFormatRg8i = 27, ImageFormatR16i = 28, ImageFormatR8i = 29, ImageFormatRgba32ui = 30, ImageFormatRgba16ui = 31, ImageFormatRgba8ui = 32, ImageFormatR32ui = 33, ImageFormatRgb10a2ui = 34, ImageFormatRg32ui = 35, ImageFormatRg16ui = 36, ImageFormatRg8ui = 37, ImageFormatR16ui = 38, ImageFormatR8ui = 39, ImageFormatR64ui = 40, ImageFormatR64i = 41, ImageFormatMax = 0x7fffffff, }; enum ImageChannelOrder { ImageChannelOrderR = 0, ImageChannelOrderA = 1, ImageChannelOrderRG = 2, ImageChannelOrderRA = 3, ImageChannelOrderRGB = 4, ImageChannelOrderRGBA = 5, ImageChannelOrderBGRA = 6, ImageChannelOrderARGB = 7, ImageChannelOrderIntensity = 8, ImageChannelOrderLuminance = 9, ImageChannelOrderRx = 10, ImageChannelOrderRGx = 11, ImageChannelOrderRGBx = 12, ImageChannelOrderDepth = 13, ImageChannelOrderDepthStencil = 14, ImageChannelOrdersRGB = 15, ImageChannelOrdersRGBx = 16, ImageChannelOrdersRGBA = 17, ImageChannelOrdersBGRA = 18, ImageChannelOrderABGR = 19, ImageChannelOrderMax = 0x7fffffff, }; enum ImageChannelDataType { ImageChannelDataTypeSnormInt8 = 0, ImageChannelDataTypeSnormInt16 = 1, ImageChannelDataTypeUnormInt8 = 2, ImageChannelDataTypeUnormInt16 = 3, ImageChannelDataTypeUnormShort565 = 4, ImageChannelDataTypeUnormShort555 = 5, ImageChannelDataTypeUnormInt101010 = 6, ImageChannelDataTypeSignedInt8 = 7, ImageChannelDataTypeSignedInt16 = 8, ImageChannelDataTypeSignedInt32 = 9, ImageChannelDataTypeUnsignedInt8 = 10, ImageChannelDataTypeUnsignedInt16 = 11, ImageChannelDataTypeUnsignedInt32 = 12, ImageChannelDataTypeHalfFloat = 13, ImageChannelDataTypeFloat = 14, ImageChannelDataTypeUnormInt24 = 15, ImageChannelDataTypeUnormInt101010_2 = 16, ImageChannelDataTypeUnormInt10X6EXT = 17, ImageChannelDataTypeUnsignedIntRaw10EXT = 19, ImageChannelDataTypeUnsignedIntRaw12EXT = 20, ImageChannelDataTypeUnormInt2_101010EXT = 21, ImageChannelDataTypeUnsignedInt10X6EXT = 22, ImageChannelDataTypeUnsignedInt12X4EXT = 23, ImageChannelDataTypeUnsignedInt14X2EXT = 24, ImageChannelDataTypeUnormInt12X4EXT = 25, ImageChannelDataTypeUnormInt14X2EXT = 26, ImageChannelDataTypeMax = 0x7fffffff, }; enum ImageOperandsShift { ImageOperandsBiasShift = 0, ImageOperandsLodShift = 1, ImageOperandsGradShift = 2, ImageOperandsConstOffsetShift = 3, ImageOperandsOffsetShift = 4, ImageOperandsConstOffsetsShift = 5, ImageOperandsSampleShift = 6, ImageOperandsMinLodShift = 7, ImageOperandsMakeTexelAvailableShift = 8, ImageOperandsMakeTexelAvailableKHRShift = 8, ImageOperandsMakeTexelVisibleShift = 9, ImageOperandsMakeTexelVisibleKHRShift = 9, ImageOperandsNonPrivateTexelShift = 10, ImageOperandsNonPrivateTexelKHRShift = 10, ImageOperandsVolatileTexelShift = 11, ImageOperandsVolatileTexelKHRShift = 11, ImageOperandsSignExtendShift = 12, ImageOperandsZeroExtendShift = 13, ImageOperandsNontemporalShift = 14, ImageOperandsOffsetsShift = 16, ImageOperandsMax = 0x7fffffff, }; enum ImageOperandsMask { ImageOperandsMaskNone = 0, ImageOperandsBiasMask = 0x00000001, ImageOperandsLodMask = 0x00000002, ImageOperandsGradMask = 0x00000004, ImageOperandsConstOffsetMask = 0x00000008, ImageOperandsOffsetMask = 0x00000010, ImageOperandsConstOffsetsMask = 0x00000020, ImageOperandsSampleMask = 0x00000040, ImageOperandsMinLodMask = 0x00000080, ImageOperandsMakeTexelAvailableMask = 0x00000100, ImageOperandsMakeTexelAvailableKHRMask = 0x00000100, ImageOperandsMakeTexelVisibleMask = 0x00000200, ImageOperandsMakeTexelVisibleKHRMask = 0x00000200, ImageOperandsNonPrivateTexelMask = 0x00000400, ImageOperandsNonPrivateTexelKHRMask = 0x00000400, ImageOperandsVolatileTexelMask = 0x00000800, ImageOperandsVolatileTexelKHRMask = 0x00000800, ImageOperandsSignExtendMask = 0x00001000, ImageOperandsZeroExtendMask = 0x00002000, ImageOperandsNontemporalMask = 0x00004000, ImageOperandsOffsetsMask = 0x00010000, }; enum FPFastMathModeShift { FPFastMathModeNotNaNShift = 0, FPFastMathModeNotInfShift = 1, FPFastMathModeNSZShift = 2, FPFastMathModeAllowRecipShift = 3, FPFastMathModeFastShift = 4, FPFastMathModeAllowContractShift = 16, FPFastMathModeAllowContractFastINTELShift = 16, FPFastMathModeAllowReassocShift = 17, FPFastMathModeAllowReassocINTELShift = 17, FPFastMathModeAllowTransformShift = 18, FPFastMathModeMax = 0x7fffffff, }; enum FPFastMathModeMask { FPFastMathModeMaskNone = 0, FPFastMathModeNotNaNMask = 0x00000001, FPFastMathModeNotInfMask = 0x00000002, FPFastMathModeNSZMask = 0x00000004, FPFastMathModeAllowRecipMask = 0x00000008, FPFastMathModeFastMask = 0x00000010, FPFastMathModeAllowContractMask = 0x00010000, FPFastMathModeAllowContractFastINTELMask = 0x00010000, FPFastMathModeAllowReassocMask = 0x00020000, FPFastMathModeAllowReassocINTELMask = 0x00020000, FPFastMathModeAllowTransformMask = 0x00040000, }; enum FPRoundingMode { FPRoundingModeRTE = 0, FPRoundingModeRTZ = 1, FPRoundingModeRTP = 2, FPRoundingModeRTN = 3, FPRoundingModeMax = 0x7fffffff, }; enum LinkageType { LinkageTypeExport = 0, LinkageTypeImport = 1, LinkageTypeLinkOnceODR = 2, LinkageTypeMax = 0x7fffffff, }; enum AccessQualifier { AccessQualifierReadOnly = 0, AccessQualifierWriteOnly = 1, AccessQualifierReadWrite = 2, AccessQualifierMax = 0x7fffffff, }; enum FunctionParameterAttribute { FunctionParameterAttributeZext = 0, FunctionParameterAttributeSext = 1, FunctionParameterAttributeByVal = 2, FunctionParameterAttributeSret = 3, FunctionParameterAttributeNoAlias = 4, FunctionParameterAttributeNoCapture = 5, FunctionParameterAttributeNoWrite = 6, FunctionParameterAttributeNoReadWrite = 7, FunctionParameterAttributeRuntimeAlignedINTEL = 5940, FunctionParameterAttributeMax = 0x7fffffff, }; enum Decoration { DecorationRelaxedPrecision = 0, DecorationSpecId = 1, DecorationBlock = 2, DecorationBufferBlock = 3, DecorationRowMajor = 4, DecorationColMajor = 5, DecorationArrayStride = 6, DecorationMatrixStride = 7, DecorationGLSLShared = 8, DecorationGLSLPacked = 9, DecorationCPacked = 10, DecorationBuiltIn = 11, DecorationNoPerspective = 13, DecorationFlat = 14, DecorationPatch = 15, DecorationCentroid = 16, DecorationSample = 17, DecorationInvariant = 18, DecorationRestrict = 19, DecorationAliased = 20, DecorationVolatile = 21, DecorationConstant = 22, DecorationCoherent = 23, DecorationNonWritable = 24, DecorationNonReadable = 25, DecorationUniform = 26, DecorationUniformId = 27, DecorationSaturatedConversion = 28, DecorationStream = 29, DecorationLocation = 30, DecorationComponent = 31, DecorationIndex = 32, DecorationBinding = 33, DecorationDescriptorSet = 34, DecorationOffset = 35, DecorationXfbBuffer = 36, DecorationXfbStride = 37, DecorationFuncParamAttr = 38, DecorationFPRoundingMode = 39, DecorationFPFastMathMode = 40, DecorationLinkageAttributes = 41, DecorationNoContraction = 42, DecorationInputAttachmentIndex = 43, DecorationAlignment = 44, DecorationMaxByteOffset = 45, DecorationAlignmentId = 46, DecorationMaxByteOffsetId = 47, DecorationSaturatedToLargestFloat8NormalConversionEXT = 4216, DecorationNoSignedWrap = 4469, DecorationNoUnsignedWrap = 4470, DecorationWeightTextureQCOM = 4487, DecorationBlockMatchTextureQCOM = 4488, DecorationBlockMatchSamplerQCOM = 4499, DecorationExplicitInterpAMD = 4999, DecorationNodeSharesPayloadLimitsWithAMDX = 5019, DecorationNodeMaxPayloadsAMDX = 5020, DecorationTrackFinishWritingAMDX = 5078, DecorationPayloadNodeNameAMDX = 5091, DecorationPayloadNodeBaseIndexAMDX = 5098, DecorationPayloadNodeSparseArrayAMDX = 5099, DecorationPayloadNodeArraySizeAMDX = 5100, DecorationPayloadDispatchIndirectAMDX = 5105, DecorationOverrideCoverageNV = 5248, DecorationPassthroughNV = 5250, DecorationViewportRelativeNV = 5252, DecorationSecondaryViewportRelativeNV = 5256, DecorationPerPrimitiveEXT = 5271, DecorationPerPrimitiveNV = 5271, DecorationPerViewNV = 5272, DecorationPerTaskNV = 5273, DecorationPerVertexKHR = 5285, DecorationPerVertexNV = 5285, DecorationNonUniform = 5300, DecorationNonUniformEXT = 5300, DecorationRestrictPointer = 5355, DecorationRestrictPointerEXT = 5355, DecorationAliasedPointer = 5356, DecorationAliasedPointerEXT = 5356, DecorationHitObjectShaderRecordBufferNV = 5386, DecorationBindlessSamplerNV = 5398, DecorationBindlessImageNV = 5399, DecorationBoundSamplerNV = 5400, DecorationBoundImageNV = 5401, DecorationSIMTCallINTEL = 5599, DecorationReferencedIndirectlyINTEL = 5602, DecorationClobberINTEL = 5607, DecorationSideEffectsINTEL = 5608, DecorationVectorComputeVariableINTEL = 5624, DecorationFuncParamIOKindINTEL = 5625, DecorationVectorComputeFunctionINTEL = 5626, DecorationStackCallINTEL = 5627, DecorationGlobalVariableOffsetINTEL = 5628, DecorationCounterBuffer = 5634, DecorationHlslCounterBufferGOOGLE = 5634, DecorationHlslSemanticGOOGLE = 5635, DecorationUserSemantic = 5635, DecorationUserTypeGOOGLE = 5636, DecorationFunctionRoundingModeINTEL = 5822, DecorationFunctionDenormModeINTEL = 5823, DecorationRegisterINTEL = 5825, DecorationMemoryINTEL = 5826, DecorationNumbanksINTEL = 5827, DecorationBankwidthINTEL = 5828, DecorationMaxPrivateCopiesINTEL = 5829, DecorationSinglepumpINTEL = 5830, DecorationDoublepumpINTEL = 5831, DecorationMaxReplicatesINTEL = 5832, DecorationSimpleDualPortINTEL = 5833, DecorationMergeINTEL = 5834, DecorationBankBitsINTEL = 5835, DecorationForcePow2DepthINTEL = 5836, DecorationStridesizeINTEL = 5883, DecorationWordsizeINTEL = 5884, DecorationTrueDualPortINTEL = 5885, DecorationBurstCoalesceINTEL = 5899, DecorationCacheSizeINTEL = 5900, DecorationDontStaticallyCoalesceINTEL = 5901, DecorationPrefetchINTEL = 5902, DecorationStallEnableINTEL = 5905, DecorationFuseLoopsInFunctionINTEL = 5907, DecorationMathOpDSPModeINTEL = 5909, DecorationAliasScopeINTEL = 5914, DecorationNoAliasINTEL = 5915, DecorationInitiationIntervalINTEL = 5917, DecorationMaxConcurrencyINTEL = 5918, DecorationPipelineEnableINTEL = 5919, DecorationBufferLocationINTEL = 5921, DecorationIOPipeStorageINTEL = 5944, DecorationFunctionFloatingPointModeINTEL = 6080, DecorationSingleElementVectorINTEL = 6085, DecorationVectorComputeCallableFunctionINTEL = 6087, DecorationMediaBlockIOINTEL = 6140, DecorationStallFreeINTEL = 6151, DecorationFPMaxErrorDecorationINTEL = 6170, DecorationLatencyControlLabelINTEL = 6172, DecorationLatencyControlConstraintINTEL = 6173, DecorationConduitKernelArgumentINTEL = 6175, DecorationRegisterMapKernelArgumentINTEL = 6176, DecorationMMHostInterfaceAddressWidthINTEL = 6177, DecorationMMHostInterfaceDataWidthINTEL = 6178, DecorationMMHostInterfaceLatencyINTEL = 6179, DecorationMMHostInterfaceReadWriteModeINTEL = 6180, DecorationMMHostInterfaceMaxBurstINTEL = 6181, DecorationMMHostInterfaceWaitRequestINTEL = 6182, DecorationStableKernelArgumentINTEL = 6183, DecorationHostAccessINTEL = 6188, DecorationInitModeINTEL = 6190, DecorationImplementInRegisterMapINTEL = 6191, DecorationConditionalINTEL = 6247, DecorationCacheControlLoadINTEL = 6442, DecorationCacheControlStoreINTEL = 6443, DecorationMax = 0x7fffffff, }; enum BuiltIn { BuiltInPosition = 0, BuiltInPointSize = 1, BuiltInClipDistance = 3, BuiltInCullDistance = 4, BuiltInVertexId = 5, BuiltInInstanceId = 6, BuiltInPrimitiveId = 7, BuiltInInvocationId = 8, BuiltInLayer = 9, BuiltInViewportIndex = 10, BuiltInTessLevelOuter = 11, BuiltInTessLevelInner = 12, BuiltInTessCoord = 13, BuiltInPatchVertices = 14, BuiltInFragCoord = 15, BuiltInPointCoord = 16, BuiltInFrontFacing = 17, BuiltInSampleId = 18, BuiltInSamplePosition = 19, BuiltInSampleMask = 20, BuiltInFragDepth = 22, BuiltInHelperInvocation = 23, BuiltInNumWorkgroups = 24, BuiltInWorkgroupSize = 25, BuiltInWorkgroupId = 26, BuiltInLocalInvocationId = 27, BuiltInGlobalInvocationId = 28, BuiltInLocalInvocationIndex = 29, BuiltInWorkDim = 30, BuiltInGlobalSize = 31, BuiltInEnqueuedWorkgroupSize = 32, BuiltInGlobalOffset = 33, BuiltInGlobalLinearId = 34, BuiltInSubgroupSize = 36, BuiltInSubgroupMaxSize = 37, BuiltInNumSubgroups = 38, BuiltInNumEnqueuedSubgroups = 39, BuiltInSubgroupId = 40, BuiltInSubgroupLocalInvocationId = 41, BuiltInVertexIndex = 42, BuiltInInstanceIndex = 43, BuiltInCoreIDARM = 4160, BuiltInCoreCountARM = 4161, BuiltInCoreMaxIDARM = 4162, BuiltInWarpIDARM = 4163, BuiltInWarpMaxIDARM = 4164, BuiltInSubgroupEqMask = 4416, BuiltInSubgroupEqMaskKHR = 4416, BuiltInSubgroupGeMask = 4417, BuiltInSubgroupGeMaskKHR = 4417, BuiltInSubgroupGtMask = 4418, BuiltInSubgroupGtMaskKHR = 4418, BuiltInSubgroupLeMask = 4419, BuiltInSubgroupLeMaskKHR = 4419, BuiltInSubgroupLtMask = 4420, BuiltInSubgroupLtMaskKHR = 4420, BuiltInBaseVertex = 4424, BuiltInBaseInstance = 4425, BuiltInDrawIndex = 4426, BuiltInPrimitiveShadingRateKHR = 4432, BuiltInDeviceIndex = 4438, BuiltInViewIndex = 4440, BuiltInShadingRateKHR = 4444, BuiltInTileOffsetQCOM = 4492, BuiltInTileDimensionQCOM = 4493, BuiltInTileApronSizeQCOM = 4494, BuiltInBaryCoordNoPerspAMD = 4992, BuiltInBaryCoordNoPerspCentroidAMD = 4993, BuiltInBaryCoordNoPerspSampleAMD = 4994, BuiltInBaryCoordSmoothAMD = 4995, BuiltInBaryCoordSmoothCentroidAMD = 4996, BuiltInBaryCoordSmoothSampleAMD = 4997, BuiltInBaryCoordPullModelAMD = 4998, BuiltInFragStencilRefEXT = 5014, BuiltInRemainingRecursionLevelsAMDX = 5021, BuiltInShaderIndexAMDX = 5073, BuiltInViewportMaskNV = 5253, BuiltInSecondaryPositionNV = 5257, BuiltInSecondaryViewportMaskNV = 5258, BuiltInPositionPerViewNV = 5261, BuiltInViewportMaskPerViewNV = 5262, BuiltInFullyCoveredEXT = 5264, BuiltInTaskCountNV = 5274, BuiltInPrimitiveCountNV = 5275, BuiltInPrimitiveIndicesNV = 5276, BuiltInClipDistancePerViewNV = 5277, BuiltInCullDistancePerViewNV = 5278, BuiltInLayerPerViewNV = 5279, BuiltInMeshViewCountNV = 5280, BuiltInMeshViewIndicesNV = 5281, BuiltInBaryCoordKHR = 5286, BuiltInBaryCoordNV = 5286, BuiltInBaryCoordNoPerspKHR = 5287, BuiltInBaryCoordNoPerspNV = 5287, BuiltInFragSizeEXT = 5292, BuiltInFragmentSizeNV = 5292, BuiltInFragInvocationCountEXT = 5293, BuiltInInvocationsPerPixelNV = 5293, BuiltInPrimitivePointIndicesEXT = 5294, BuiltInPrimitiveLineIndicesEXT = 5295, BuiltInPrimitiveTriangleIndicesEXT = 5296, BuiltInCullPrimitiveEXT = 5299, BuiltInLaunchIdKHR = 5319, BuiltInLaunchIdNV = 5319, BuiltInLaunchSizeKHR = 5320, BuiltInLaunchSizeNV = 5320, BuiltInWorldRayOriginKHR = 5321, BuiltInWorldRayOriginNV = 5321, BuiltInWorldRayDirectionKHR = 5322, BuiltInWorldRayDirectionNV = 5322, BuiltInObjectRayOriginKHR = 5323, BuiltInObjectRayOriginNV = 5323, BuiltInObjectRayDirectionKHR = 5324, BuiltInObjectRayDirectionNV = 5324, BuiltInRayTminKHR = 5325, BuiltInRayTminNV = 5325, BuiltInRayTmaxKHR = 5326, BuiltInRayTmaxNV = 5326, BuiltInInstanceCustomIndexKHR = 5327, BuiltInInstanceCustomIndexNV = 5327, BuiltInObjectToWorldKHR = 5330, BuiltInObjectToWorldNV = 5330, BuiltInWorldToObjectKHR = 5331, BuiltInWorldToObjectNV = 5331, BuiltInHitTNV = 5332, BuiltInHitKindKHR = 5333, BuiltInHitKindNV = 5333, BuiltInCurrentRayTimeNV = 5334, BuiltInHitTriangleVertexPositionsKHR = 5335, BuiltInHitMicroTriangleVertexPositionsNV = 5337, BuiltInHitMicroTriangleVertexBarycentricsNV = 5344, BuiltInIncomingRayFlagsKHR = 5351, BuiltInIncomingRayFlagsNV = 5351, BuiltInRayGeometryIndexKHR = 5352, BuiltInHitIsSphereNV = 5359, BuiltInHitIsLSSNV = 5360, BuiltInHitSpherePositionNV = 5361, BuiltInWarpsPerSMNV = 5374, BuiltInSMCountNV = 5375, BuiltInWarpIDNV = 5376, BuiltInSMIDNV = 5377, BuiltInHitLSSPositionsNV = 5396, BuiltInHitKindFrontFacingMicroTriangleNV = 5405, BuiltInHitKindBackFacingMicroTriangleNV = 5406, BuiltInHitSphereRadiusNV = 5420, BuiltInHitLSSRadiiNV = 5421, BuiltInClusterIDNV = 5436, BuiltInCullMaskKHR = 6021, BuiltInMax = 0x7fffffff, }; enum SelectionControlShift { SelectionControlFlattenShift = 0, SelectionControlDontFlattenShift = 1, SelectionControlMax = 0x7fffffff, }; enum SelectionControlMask { SelectionControlMaskNone = 0, SelectionControlFlattenMask = 0x00000001, SelectionControlDontFlattenMask = 0x00000002, }; enum LoopControlShift { LoopControlUnrollShift = 0, LoopControlDontUnrollShift = 1, LoopControlDependencyInfiniteShift = 2, LoopControlDependencyLengthShift = 3, LoopControlMinIterationsShift = 4, LoopControlMaxIterationsShift = 5, LoopControlIterationMultipleShift = 6, LoopControlPeelCountShift = 7, LoopControlPartialCountShift = 8, LoopControlInitiationIntervalINTELShift = 16, LoopControlMaxConcurrencyINTELShift = 17, LoopControlDependencyArrayINTELShift = 18, LoopControlPipelineEnableINTELShift = 19, LoopControlLoopCoalesceINTELShift = 20, LoopControlMaxInterleavingINTELShift = 21, LoopControlSpeculatedIterationsINTELShift = 22, LoopControlNoFusionINTELShift = 23, LoopControlLoopCountINTELShift = 24, LoopControlMaxReinvocationDelayINTELShift = 25, LoopControlMax = 0x7fffffff, }; enum LoopControlMask { LoopControlMaskNone = 0, LoopControlUnrollMask = 0x00000001, LoopControlDontUnrollMask = 0x00000002, LoopControlDependencyInfiniteMask = 0x00000004, LoopControlDependencyLengthMask = 0x00000008, LoopControlMinIterationsMask = 0x00000010, LoopControlMaxIterationsMask = 0x00000020, LoopControlIterationMultipleMask = 0x00000040, LoopControlPeelCountMask = 0x00000080, LoopControlPartialCountMask = 0x00000100, LoopControlInitiationIntervalINTELMask = 0x00010000, LoopControlMaxConcurrencyINTELMask = 0x00020000, LoopControlDependencyArrayINTELMask = 0x00040000, LoopControlPipelineEnableINTELMask = 0x00080000, LoopControlLoopCoalesceINTELMask = 0x00100000, LoopControlMaxInterleavingINTELMask = 0x00200000, LoopControlSpeculatedIterationsINTELMask = 0x00400000, LoopControlNoFusionINTELMask = 0x00800000, LoopControlLoopCountINTELMask = 0x01000000, LoopControlMaxReinvocationDelayINTELMask = 0x02000000, }; enum FunctionControlShift { FunctionControlInlineShift = 0, FunctionControlDontInlineShift = 1, FunctionControlPureShift = 2, FunctionControlConstShift = 3, FunctionControlOptNoneEXTShift = 16, FunctionControlOptNoneINTELShift = 16, FunctionControlMax = 0x7fffffff, }; enum FunctionControlMask { FunctionControlMaskNone = 0, FunctionControlInlineMask = 0x00000001, FunctionControlDontInlineMask = 0x00000002, FunctionControlPureMask = 0x00000004, FunctionControlConstMask = 0x00000008, FunctionControlOptNoneEXTMask = 0x00010000, FunctionControlOptNoneINTELMask = 0x00010000, }; enum MemorySemanticsShift { MemorySemanticsAcquireShift = 1, MemorySemanticsReleaseShift = 2, MemorySemanticsAcquireReleaseShift = 3, MemorySemanticsSequentiallyConsistentShift = 4, MemorySemanticsUniformMemoryShift = 6, MemorySemanticsSubgroupMemoryShift = 7, MemorySemanticsWorkgroupMemoryShift = 8, MemorySemanticsCrossWorkgroupMemoryShift = 9, MemorySemanticsAtomicCounterMemoryShift = 10, MemorySemanticsImageMemoryShift = 11, MemorySemanticsOutputMemoryShift = 12, MemorySemanticsOutputMemoryKHRShift = 12, MemorySemanticsMakeAvailableShift = 13, MemorySemanticsMakeAvailableKHRShift = 13, MemorySemanticsMakeVisibleShift = 14, MemorySemanticsMakeVisibleKHRShift = 14, MemorySemanticsVolatileShift = 15, MemorySemanticsMax = 0x7fffffff, }; enum MemorySemanticsMask { MemorySemanticsMaskNone = 0, MemorySemanticsAcquireMask = 0x00000002, MemorySemanticsReleaseMask = 0x00000004, MemorySemanticsAcquireReleaseMask = 0x00000008, MemorySemanticsSequentiallyConsistentMask = 0x00000010, MemorySemanticsUniformMemoryMask = 0x00000040, MemorySemanticsSubgroupMemoryMask = 0x00000080, MemorySemanticsWorkgroupMemoryMask = 0x00000100, MemorySemanticsCrossWorkgroupMemoryMask = 0x00000200, MemorySemanticsAtomicCounterMemoryMask = 0x00000400, MemorySemanticsImageMemoryMask = 0x00000800, MemorySemanticsOutputMemoryMask = 0x00001000, MemorySemanticsOutputMemoryKHRMask = 0x00001000, MemorySemanticsMakeAvailableMask = 0x00002000, MemorySemanticsMakeAvailableKHRMask = 0x00002000, MemorySemanticsMakeVisibleMask = 0x00004000, MemorySemanticsMakeVisibleKHRMask = 0x00004000, MemorySemanticsVolatileMask = 0x00008000, }; enum MemoryAccessShift { MemoryAccessVolatileShift = 0, MemoryAccessAlignedShift = 1, MemoryAccessNontemporalShift = 2, MemoryAccessMakePointerAvailableShift = 3, MemoryAccessMakePointerAvailableKHRShift = 3, MemoryAccessMakePointerVisibleShift = 4, MemoryAccessMakePointerVisibleKHRShift = 4, MemoryAccessNonPrivatePointerShift = 5, MemoryAccessNonPrivatePointerKHRShift = 5, MemoryAccessAliasScopeINTELMaskShift = 16, MemoryAccessNoAliasINTELMaskShift = 17, MemoryAccessMax = 0x7fffffff, }; enum MemoryAccessMask { MemoryAccessMaskNone = 0, MemoryAccessVolatileMask = 0x00000001, MemoryAccessAlignedMask = 0x00000002, MemoryAccessNontemporalMask = 0x00000004, MemoryAccessMakePointerAvailableMask = 0x00000008, MemoryAccessMakePointerAvailableKHRMask = 0x00000008, MemoryAccessMakePointerVisibleMask = 0x00000010, MemoryAccessMakePointerVisibleKHRMask = 0x00000010, MemoryAccessNonPrivatePointerMask = 0x00000020, MemoryAccessNonPrivatePointerKHRMask = 0x00000020, MemoryAccessAliasScopeINTELMaskMask = 0x00010000, MemoryAccessNoAliasINTELMaskMask = 0x00020000, }; enum Scope { ScopeCrossDevice = 0, ScopeDevice = 1, ScopeWorkgroup = 2, ScopeSubgroup = 3, ScopeInvocation = 4, ScopeQueueFamily = 5, ScopeQueueFamilyKHR = 5, ScopeShaderCallKHR = 6, ScopeMax = 0x7fffffff, }; enum GroupOperation { GroupOperationReduce = 0, GroupOperationInclusiveScan = 1, GroupOperationExclusiveScan = 2, GroupOperationClusteredReduce = 3, GroupOperationPartitionedReduceNV = 6, GroupOperationPartitionedInclusiveScanNV = 7, GroupOperationPartitionedExclusiveScanNV = 8, GroupOperationMax = 0x7fffffff, }; enum KernelEnqueueFlags { KernelEnqueueFlagsNoWait = 0, KernelEnqueueFlagsWaitKernel = 1, KernelEnqueueFlagsWaitWorkGroup = 2, KernelEnqueueFlagsMax = 0x7fffffff, }; enum KernelProfilingInfoShift { KernelProfilingInfoCmdExecTimeShift = 0, KernelProfilingInfoMax = 0x7fffffff, }; enum KernelProfilingInfoMask { KernelProfilingInfoMaskNone = 0, KernelProfilingInfoCmdExecTimeMask = 0x00000001, }; enum Capability { CapabilityMatrix = 0, CapabilityShader = 1, CapabilityGeometry = 2, CapabilityTessellation = 3, CapabilityAddresses = 4, CapabilityLinkage = 5, CapabilityKernel = 6, CapabilityVector16 = 7, CapabilityFloat16Buffer = 8, CapabilityFloat16 = 9, CapabilityFloat64 = 10, CapabilityInt64 = 11, CapabilityInt64Atomics = 12, CapabilityImageBasic = 13, CapabilityImageReadWrite = 14, CapabilityImageMipmap = 15, CapabilityPipes = 17, CapabilityGroups = 18, CapabilityDeviceEnqueue = 19, CapabilityLiteralSampler = 20, CapabilityAtomicStorage = 21, CapabilityInt16 = 22, CapabilityTessellationPointSize = 23, CapabilityGeometryPointSize = 24, CapabilityImageGatherExtended = 25, CapabilityStorageImageMultisample = 27, CapabilityUniformBufferArrayDynamicIndexing = 28, CapabilitySampledImageArrayDynamicIndexing = 29, CapabilityStorageBufferArrayDynamicIndexing = 30, CapabilityStorageImageArrayDynamicIndexing = 31, CapabilityClipDistance = 32, CapabilityCullDistance = 33, CapabilityImageCubeArray = 34, CapabilitySampleRateShading = 35, CapabilityImageRect = 36, CapabilitySampledRect = 37, CapabilityGenericPointer = 38, CapabilityInt8 = 39, CapabilityInputAttachment = 40, CapabilitySparseResidency = 41, CapabilityMinLod = 42, CapabilitySampled1D = 43, CapabilityImage1D = 44, CapabilitySampledCubeArray = 45, CapabilitySampledBuffer = 46, CapabilityImageBuffer = 47, CapabilityImageMSArray = 48, CapabilityStorageImageExtendedFormats = 49, CapabilityImageQuery = 50, CapabilityDerivativeControl = 51, CapabilityInterpolationFunction = 52, CapabilityTransformFeedback = 53, CapabilityGeometryStreams = 54, CapabilityStorageImageReadWithoutFormat = 55, CapabilityStorageImageWriteWithoutFormat = 56, CapabilityMultiViewport = 57, CapabilitySubgroupDispatch = 58, CapabilityNamedBarrier = 59, CapabilityPipeStorage = 60, CapabilityGroupNonUniform = 61, CapabilityGroupNonUniformVote = 62, CapabilityGroupNonUniformArithmetic = 63, CapabilityGroupNonUniformBallot = 64, CapabilityGroupNonUniformShuffle = 65, CapabilityGroupNonUniformShuffleRelative = 66, CapabilityGroupNonUniformClustered = 67, CapabilityGroupNonUniformQuad = 68, CapabilityShaderLayer = 69, CapabilityShaderViewportIndex = 70, CapabilityUniformDecoration = 71, CapabilityCoreBuiltinsARM = 4165, CapabilityTileImageColorReadAccessEXT = 4166, CapabilityTileImageDepthReadAccessEXT = 4167, CapabilityTileImageStencilReadAccessEXT = 4168, CapabilityTensorsARM = 4174, CapabilityStorageTensorArrayDynamicIndexingARM = 4175, CapabilityStorageTensorArrayNonUniformIndexingARM = 4176, CapabilityGraphARM = 4191, CapabilityCooperativeMatrixLayoutsARM = 4201, CapabilityFloat8EXT = 4212, CapabilityFloat8CooperativeMatrixEXT = 4213, CapabilityFragmentShadingRateKHR = 4422, CapabilitySubgroupBallotKHR = 4423, CapabilityDrawParameters = 4427, CapabilityWorkgroupMemoryExplicitLayoutKHR = 4428, CapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR = 4429, CapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR = 4430, CapabilitySubgroupVoteKHR = 4431, CapabilityStorageBuffer16BitAccess = 4433, CapabilityStorageUniformBufferBlock16 = 4433, CapabilityStorageUniform16 = 4434, CapabilityUniformAndStorageBuffer16BitAccess = 4434, CapabilityStoragePushConstant16 = 4435, CapabilityStorageInputOutput16 = 4436, CapabilityDeviceGroup = 4437, CapabilityMultiView = 4439, CapabilityVariablePointersStorageBuffer = 4441, CapabilityVariablePointers = 4442, CapabilityAtomicStorageOps = 4445, CapabilitySampleMaskPostDepthCoverage = 4447, CapabilityStorageBuffer8BitAccess = 4448, CapabilityUniformAndStorageBuffer8BitAccess = 4449, CapabilityStoragePushConstant8 = 4450, CapabilityDenormPreserve = 4464, CapabilityDenormFlushToZero = 4465, CapabilitySignedZeroInfNanPreserve = 4466, CapabilityRoundingModeRTE = 4467, CapabilityRoundingModeRTZ = 4468, CapabilityRayQueryProvisionalKHR = 4471, CapabilityRayQueryKHR = 4472, CapabilityUntypedPointersKHR = 4473, CapabilityRayTraversalPrimitiveCullingKHR = 4478, CapabilityRayTracingKHR = 4479, CapabilityTextureSampleWeightedQCOM = 4484, CapabilityTextureBoxFilterQCOM = 4485, CapabilityTextureBlockMatchQCOM = 4486, CapabilityTileShadingQCOM = 4495, CapabilityCooperativeMatrixConversionQCOM = 4496, CapabilityTextureBlockMatch2QCOM = 4498, CapabilityFloat16ImageAMD = 5008, CapabilityImageGatherBiasLodAMD = 5009, CapabilityFragmentMaskAMD = 5010, CapabilityStencilExportEXT = 5013, CapabilityImageReadWriteLodAMD = 5015, CapabilityInt64ImageEXT = 5016, CapabilityShaderClockKHR = 5055, CapabilityShaderEnqueueAMDX = 5067, CapabilityQuadControlKHR = 5087, CapabilityInt4TypeINTEL = 5112, CapabilityInt4CooperativeMatrixINTEL = 5114, CapabilityBFloat16TypeKHR = 5116, CapabilityBFloat16DotProductKHR = 5117, CapabilityBFloat16CooperativeMatrixKHR = 5118, CapabilitySampleMaskOverrideCoverageNV = 5249, CapabilityGeometryShaderPassthroughNV = 5251, CapabilityShaderViewportIndexLayerEXT = 5254, CapabilityShaderViewportIndexLayerNV = 5254, CapabilityShaderViewportMaskNV = 5255, CapabilityShaderStereoViewNV = 5259, CapabilityPerViewAttributesNV = 5260, CapabilityFragmentFullyCoveredEXT = 5265, CapabilityMeshShadingNV = 5266, CapabilityImageFootprintNV = 5282, CapabilityMeshShadingEXT = 5283, CapabilityFragmentBarycentricKHR = 5284, CapabilityFragmentBarycentricNV = 5284, CapabilityComputeDerivativeGroupQuadsKHR = 5288, CapabilityComputeDerivativeGroupQuadsNV = 5288, CapabilityFragmentDensityEXT = 5291, CapabilityShadingRateNV = 5291, CapabilityGroupNonUniformPartitionedNV = 5297, CapabilityShaderNonUniform = 5301, CapabilityShaderNonUniformEXT = 5301, CapabilityRuntimeDescriptorArray = 5302, CapabilityRuntimeDescriptorArrayEXT = 5302, CapabilityInputAttachmentArrayDynamicIndexing = 5303, CapabilityInputAttachmentArrayDynamicIndexingEXT = 5303, CapabilityUniformTexelBufferArrayDynamicIndexing = 5304, CapabilityUniformTexelBufferArrayDynamicIndexingEXT = 5304, CapabilityStorageTexelBufferArrayDynamicIndexing = 5305, CapabilityStorageTexelBufferArrayDynamicIndexingEXT = 5305, CapabilityUniformBufferArrayNonUniformIndexing = 5306, CapabilityUniformBufferArrayNonUniformIndexingEXT = 5306, CapabilitySampledImageArrayNonUniformIndexing = 5307, CapabilitySampledImageArrayNonUniformIndexingEXT = 5307, CapabilityStorageBufferArrayNonUniformIndexing = 5308, CapabilityStorageBufferArrayNonUniformIndexingEXT = 5308, CapabilityStorageImageArrayNonUniformIndexing = 5309, CapabilityStorageImageArrayNonUniformIndexingEXT = 5309, CapabilityInputAttachmentArrayNonUniformIndexing = 5310, CapabilityInputAttachmentArrayNonUniformIndexingEXT = 5310, CapabilityUniformTexelBufferArrayNonUniformIndexing = 5311, CapabilityUniformTexelBufferArrayNonUniformIndexingEXT = 5311, CapabilityStorageTexelBufferArrayNonUniformIndexing = 5312, CapabilityStorageTexelBufferArrayNonUniformIndexingEXT = 5312, CapabilityRayTracingPositionFetchKHR = 5336, CapabilityRayTracingNV = 5340, CapabilityRayTracingMotionBlurNV = 5341, CapabilityVulkanMemoryModel = 5345, CapabilityVulkanMemoryModelKHR = 5345, CapabilityVulkanMemoryModelDeviceScope = 5346, CapabilityVulkanMemoryModelDeviceScopeKHR = 5346, CapabilityPhysicalStorageBufferAddresses = 5347, CapabilityPhysicalStorageBufferAddressesEXT = 5347, CapabilityComputeDerivativeGroupLinearKHR = 5350, CapabilityComputeDerivativeGroupLinearNV = 5350, CapabilityRayTracingProvisionalKHR = 5353, CapabilityCooperativeMatrixNV = 5357, CapabilityFragmentShaderSampleInterlockEXT = 5363, CapabilityFragmentShaderShadingRateInterlockEXT = 5372, CapabilityShaderSMBuiltinsNV = 5373, CapabilityFragmentShaderPixelInterlockEXT = 5378, CapabilityDemoteToHelperInvocation = 5379, CapabilityDemoteToHelperInvocationEXT = 5379, CapabilityDisplacementMicromapNV = 5380, CapabilityRayTracingOpacityMicromapEXT = 5381, CapabilityShaderInvocationReorderNV = 5383, CapabilityBindlessTextureNV = 5390, CapabilityRayQueryPositionFetchKHR = 5391, CapabilityCooperativeVectorNV = 5394, CapabilityAtomicFloat16VectorNV = 5404, CapabilityRayTracingDisplacementMicromapNV = 5409, CapabilityRawAccessChainsNV = 5414, CapabilityRayTracingSpheresGeometryNV = 5418, CapabilityRayTracingLinearSweptSpheresGeometryNV = 5419, CapabilityCooperativeMatrixReductionsNV = 5430, CapabilityCooperativeMatrixConversionsNV = 5431, CapabilityCooperativeMatrixPerElementOperationsNV = 5432, CapabilityCooperativeMatrixTensorAddressingNV = 5433, CapabilityCooperativeMatrixBlockLoadsNV = 5434, CapabilityCooperativeVectorTrainingNV = 5435, CapabilityRayTracingClusterAccelerationStructureNV = 5437, CapabilityTensorAddressingNV = 5439, CapabilitySubgroupShuffleINTEL = 5568, CapabilitySubgroupBufferBlockIOINTEL = 5569, CapabilitySubgroupImageBlockIOINTEL = 5570, CapabilitySubgroupImageMediaBlockIOINTEL = 5579, CapabilityRoundToInfinityINTEL = 5582, CapabilityFloatingPointModeINTEL = 5583, CapabilityIntegerFunctions2INTEL = 5584, CapabilityFunctionPointersINTEL = 5603, CapabilityIndirectReferencesINTEL = 5604, CapabilityAsmINTEL = 5606, CapabilityAtomicFloat32MinMaxEXT = 5612, CapabilityAtomicFloat64MinMaxEXT = 5613, CapabilityAtomicFloat16MinMaxEXT = 5616, CapabilityVectorComputeINTEL = 5617, CapabilityVectorAnyINTEL = 5619, CapabilityExpectAssumeKHR = 5629, CapabilitySubgroupAvcMotionEstimationINTEL = 5696, CapabilitySubgroupAvcMotionEstimationIntraINTEL = 5697, CapabilitySubgroupAvcMotionEstimationChromaINTEL = 5698, CapabilityVariableLengthArrayINTEL = 5817, CapabilityFunctionFloatControlINTEL = 5821, CapabilityFPGAMemoryAttributesINTEL = 5824, CapabilityFPFastMathModeINTEL = 5837, CapabilityArbitraryPrecisionIntegersINTEL = 5844, CapabilityArbitraryPrecisionFloatingPointINTEL = 5845, CapabilityUnstructuredLoopControlsINTEL = 5886, CapabilityFPGALoopControlsINTEL = 5888, CapabilityKernelAttributesINTEL = 5892, CapabilityFPGAKernelAttributesINTEL = 5897, CapabilityFPGAMemoryAccessesINTEL = 5898, CapabilityFPGAClusterAttributesINTEL = 5904, CapabilityLoopFuseINTEL = 5906, CapabilityFPGADSPControlINTEL = 5908, CapabilityMemoryAccessAliasingINTEL = 5910, CapabilityFPGAInvocationPipeliningAttributesINTEL = 5916, CapabilityFPGABufferLocationINTEL = 5920, CapabilityArbitraryPrecisionFixedPointINTEL = 5922, CapabilityUSMStorageClassesINTEL = 5935, CapabilityRuntimeAlignedAttributeINTEL = 5939, CapabilityIOPipesINTEL = 5943, CapabilityBlockingPipesINTEL = 5945, CapabilityFPGARegINTEL = 5948, CapabilityDotProductInputAll = 6016, CapabilityDotProductInputAllKHR = 6016, CapabilityDotProductInput4x8Bit = 6017, CapabilityDotProductInput4x8BitKHR = 6017, CapabilityDotProductInput4x8BitPacked = 6018, CapabilityDotProductInput4x8BitPackedKHR = 6018, CapabilityDotProduct = 6019, CapabilityDotProductKHR = 6019, CapabilityRayCullMaskKHR = 6020, CapabilityCooperativeMatrixKHR = 6022, CapabilityReplicatedCompositesEXT = 6024, CapabilityBitInstructions = 6025, CapabilityGroupNonUniformRotateKHR = 6026, CapabilityFloatControls2 = 6029, CapabilityAtomicFloat32AddEXT = 6033, CapabilityAtomicFloat64AddEXT = 6034, CapabilityLongCompositesINTEL = 6089, CapabilityOptNoneEXT = 6094, CapabilityOptNoneINTEL = 6094, CapabilityAtomicFloat16AddEXT = 6095, CapabilityDebugInfoModuleINTEL = 6114, CapabilityBFloat16ConversionINTEL = 6115, CapabilitySplitBarrierINTEL = 6141, CapabilityArithmeticFenceEXT = 6144, CapabilityFPGAClusterAttributesV2INTEL = 6150, CapabilityFPGAKernelAttributesv2INTEL = 6161, CapabilityTaskSequenceINTEL = 6162, CapabilityFPMaxErrorINTEL = 6169, CapabilityFPGALatencyControlINTEL = 6171, CapabilityFPGAArgumentInterfacesINTEL = 6174, CapabilityGlobalVariableHostAccessINTEL = 6187, CapabilityGlobalVariableFPGADecorationsINTEL = 6189, CapabilitySubgroupBufferPrefetchINTEL = 6220, CapabilitySubgroup2DBlockIOINTEL = 6228, CapabilitySubgroup2DBlockTransformINTEL = 6229, CapabilitySubgroup2DBlockTransposeINTEL = 6230, CapabilitySubgroupMatrixMultiplyAccumulateINTEL = 6236, CapabilityTernaryBitwiseFunctionINTEL = 6241, CapabilitySpecConditionalINTEL = 6245, CapabilityFunctionVariantsINTEL = 6246, CapabilityGroupUniformArithmeticKHR = 6400, CapabilityTensorFloat32RoundingINTEL = 6425, CapabilityMaskedGatherScatterINTEL = 6427, CapabilityCacheControlsINTEL = 6441, CapabilityRegisterLimitsINTEL = 6460, CapabilityBindlessImagesINTEL = 6528, CapabilityMax = 0x7fffffff, }; enum RayFlagsShift { RayFlagsOpaqueKHRShift = 0, RayFlagsNoOpaqueKHRShift = 1, RayFlagsTerminateOnFirstHitKHRShift = 2, RayFlagsSkipClosestHitShaderKHRShift = 3, RayFlagsCullBackFacingTrianglesKHRShift = 4, RayFlagsCullFrontFacingTrianglesKHRShift = 5, RayFlagsCullOpaqueKHRShift = 6, RayFlagsCullNoOpaqueKHRShift = 7, RayFlagsSkipBuiltinPrimitivesNVShift = 8, RayFlagsSkipTrianglesKHRShift = 8, RayFlagsSkipAABBsKHRShift = 9, RayFlagsForceOpacityMicromap2StateEXTShift = 10, RayFlagsMax = 0x7fffffff, }; enum RayFlagsMask { RayFlagsMaskNone = 0, RayFlagsOpaqueKHRMask = 0x00000001, RayFlagsNoOpaqueKHRMask = 0x00000002, RayFlagsTerminateOnFirstHitKHRMask = 0x00000004, RayFlagsSkipClosestHitShaderKHRMask = 0x00000008, RayFlagsCullBackFacingTrianglesKHRMask = 0x00000010, RayFlagsCullFrontFacingTrianglesKHRMask = 0x00000020, RayFlagsCullOpaqueKHRMask = 0x00000040, RayFlagsCullNoOpaqueKHRMask = 0x00000080, RayFlagsSkipBuiltinPrimitivesNVMask = 0x00000100, RayFlagsSkipTrianglesKHRMask = 0x00000100, RayFlagsSkipAABBsKHRMask = 0x00000200, RayFlagsForceOpacityMicromap2StateEXTMask = 0x00000400, }; enum RayQueryIntersection { RayQueryIntersectionRayQueryCandidateIntersectionKHR = 0, RayQueryIntersectionRayQueryCommittedIntersectionKHR = 1, RayQueryIntersectionMax = 0x7fffffff, }; enum RayQueryCommittedIntersectionType { RayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionNoneKHR = 0, RayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionTriangleKHR = 1, RayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionGeneratedKHR = 2, RayQueryCommittedIntersectionTypeMax = 0x7fffffff, }; enum RayQueryCandidateIntersectionType { RayQueryCandidateIntersectionTypeRayQueryCandidateIntersectionTriangleKHR = 0, RayQueryCandidateIntersectionTypeRayQueryCandidateIntersectionAABBKHR = 1, RayQueryCandidateIntersectionTypeMax = 0x7fffffff, }; enum FragmentShadingRateShift { FragmentShadingRateVertical2PixelsShift = 0, FragmentShadingRateVertical4PixelsShift = 1, FragmentShadingRateHorizontal2PixelsShift = 2, FragmentShadingRateHorizontal4PixelsShift = 3, FragmentShadingRateMax = 0x7fffffff, }; enum FragmentShadingRateMask { FragmentShadingRateMaskNone = 0, FragmentShadingRateVertical2PixelsMask = 0x00000001, FragmentShadingRateVertical4PixelsMask = 0x00000002, FragmentShadingRateHorizontal2PixelsMask = 0x00000004, FragmentShadingRateHorizontal4PixelsMask = 0x00000008, }; enum FPDenormMode { FPDenormModePreserve = 0, FPDenormModeFlushToZero = 1, FPDenormModeMax = 0x7fffffff, }; enum FPOperationMode { FPOperationModeIEEE = 0, FPOperationModeALT = 1, FPOperationModeMax = 0x7fffffff, }; enum QuantizationModes { QuantizationModesTRN = 0, QuantizationModesTRN_ZERO = 1, QuantizationModesRND = 2, QuantizationModesRND_ZERO = 3, QuantizationModesRND_INF = 4, QuantizationModesRND_MIN_INF = 5, QuantizationModesRND_CONV = 6, QuantizationModesRND_CONV_ODD = 7, QuantizationModesMax = 0x7fffffff, }; enum OverflowModes { OverflowModesWRAP = 0, OverflowModesSAT = 1, OverflowModesSAT_ZERO = 2, OverflowModesSAT_SYM = 3, OverflowModesMax = 0x7fffffff, }; enum PackedVectorFormat { PackedVectorFormatPackedVectorFormat4x8Bit = 0, PackedVectorFormatPackedVectorFormat4x8BitKHR = 0, PackedVectorFormatMax = 0x7fffffff, }; enum CooperativeMatrixOperandsShift { CooperativeMatrixOperandsMatrixASignedComponentsKHRShift = 0, CooperativeMatrixOperandsMatrixBSignedComponentsKHRShift = 1, CooperativeMatrixOperandsMatrixCSignedComponentsKHRShift = 2, CooperativeMatrixOperandsMatrixResultSignedComponentsKHRShift = 3, CooperativeMatrixOperandsSaturatingAccumulationKHRShift = 4, CooperativeMatrixOperandsMax = 0x7fffffff, }; enum CooperativeMatrixOperandsMask { CooperativeMatrixOperandsMaskNone = 0, CooperativeMatrixOperandsMatrixASignedComponentsKHRMask = 0x00000001, CooperativeMatrixOperandsMatrixBSignedComponentsKHRMask = 0x00000002, CooperativeMatrixOperandsMatrixCSignedComponentsKHRMask = 0x00000004, CooperativeMatrixOperandsMatrixResultSignedComponentsKHRMask = 0x00000008, CooperativeMatrixOperandsSaturatingAccumulationKHRMask = 0x00000010, }; enum CooperativeMatrixLayout { CooperativeMatrixLayoutRowMajorKHR = 0, CooperativeMatrixLayoutColumnMajorKHR = 1, CooperativeMatrixLayoutRowBlockedInterleavedARM = 4202, CooperativeMatrixLayoutColumnBlockedInterleavedARM = 4203, CooperativeMatrixLayoutMax = 0x7fffffff, }; enum CooperativeMatrixUse { CooperativeMatrixUseMatrixAKHR = 0, CooperativeMatrixUseMatrixBKHR = 1, CooperativeMatrixUseMatrixAccumulatorKHR = 2, CooperativeMatrixUseMax = 0x7fffffff, }; enum CooperativeMatrixReduceShift { CooperativeMatrixReduceRowShift = 0, CooperativeMatrixReduceColumnShift = 1, CooperativeMatrixReduce2x2Shift = 2, CooperativeMatrixReduceMax = 0x7fffffff, }; enum CooperativeMatrixReduceMask { CooperativeMatrixReduceMaskNone = 0, CooperativeMatrixReduceRowMask = 0x00000001, CooperativeMatrixReduceColumnMask = 0x00000002, CooperativeMatrixReduce2x2Mask = 0x00000004, }; enum TensorClampMode { TensorClampModeUndefined = 0, TensorClampModeConstant = 1, TensorClampModeClampToEdge = 2, TensorClampModeRepeat = 3, TensorClampModeRepeatMirrored = 4, TensorClampModeMax = 0x7fffffff, }; enum TensorAddressingOperandsShift { TensorAddressingOperandsTensorViewShift = 0, TensorAddressingOperandsDecodeFuncShift = 1, TensorAddressingOperandsMax = 0x7fffffff, }; enum TensorAddressingOperandsMask { TensorAddressingOperandsMaskNone = 0, TensorAddressingOperandsTensorViewMask = 0x00000001, TensorAddressingOperandsDecodeFuncMask = 0x00000002, }; enum TensorOperandsShift { TensorOperandsNontemporalARMShift = 0, TensorOperandsOutOfBoundsValueARMShift = 1, TensorOperandsMakeElementAvailableARMShift = 2, TensorOperandsMakeElementVisibleARMShift = 3, TensorOperandsNonPrivateElementARMShift = 4, TensorOperandsMax = 0x7fffffff, }; enum TensorOperandsMask { TensorOperandsMaskNone = 0, TensorOperandsNontemporalARMMask = 0x00000001, TensorOperandsOutOfBoundsValueARMMask = 0x00000002, TensorOperandsMakeElementAvailableARMMask = 0x00000004, TensorOperandsMakeElementVisibleARMMask = 0x00000008, TensorOperandsNonPrivateElementARMMask = 0x00000010, }; enum InitializationModeQualifier { InitializationModeQualifierInitOnDeviceReprogramINTEL = 0, InitializationModeQualifierInitOnDeviceResetINTEL = 1, InitializationModeQualifierMax = 0x7fffffff, }; enum HostAccessQualifier { HostAccessQualifierNoneINTEL = 0, HostAccessQualifierReadINTEL = 1, HostAccessQualifierWriteINTEL = 2, HostAccessQualifierReadWriteINTEL = 3, HostAccessQualifierMax = 0x7fffffff, }; enum LoadCacheControl { LoadCacheControlUncachedINTEL = 0, LoadCacheControlCachedINTEL = 1, LoadCacheControlStreamingINTEL = 2, LoadCacheControlInvalidateAfterReadINTEL = 3, LoadCacheControlConstCachedINTEL = 4, LoadCacheControlMax = 0x7fffffff, }; enum StoreCacheControl { StoreCacheControlUncachedINTEL = 0, StoreCacheControlWriteThroughINTEL = 1, StoreCacheControlWriteBackINTEL = 2, StoreCacheControlStreamingINTEL = 3, StoreCacheControlMax = 0x7fffffff, }; enum NamedMaximumNumberOfRegisters { NamedMaximumNumberOfRegistersAutoINTEL = 0, NamedMaximumNumberOfRegistersMax = 0x7fffffff, }; enum MatrixMultiplyAccumulateOperandsShift { MatrixMultiplyAccumulateOperandsMatrixASignedComponentsINTELShift = 0, MatrixMultiplyAccumulateOperandsMatrixBSignedComponentsINTELShift = 1, MatrixMultiplyAccumulateOperandsMatrixCBFloat16INTELShift = 2, MatrixMultiplyAccumulateOperandsMatrixResultBFloat16INTELShift = 3, MatrixMultiplyAccumulateOperandsMatrixAPackedInt8INTELShift = 4, MatrixMultiplyAccumulateOperandsMatrixBPackedInt8INTELShift = 5, MatrixMultiplyAccumulateOperandsMatrixAPackedInt4INTELShift = 6, MatrixMultiplyAccumulateOperandsMatrixBPackedInt4INTELShift = 7, MatrixMultiplyAccumulateOperandsMatrixATF32INTELShift = 8, MatrixMultiplyAccumulateOperandsMatrixBTF32INTELShift = 9, MatrixMultiplyAccumulateOperandsMatrixAPackedFloat16INTELShift = 10, MatrixMultiplyAccumulateOperandsMatrixBPackedFloat16INTELShift = 11, MatrixMultiplyAccumulateOperandsMatrixAPackedBFloat16INTELShift = 12, MatrixMultiplyAccumulateOperandsMatrixBPackedBFloat16INTELShift = 13, MatrixMultiplyAccumulateOperandsMax = 0x7fffffff, }; enum MatrixMultiplyAccumulateOperandsMask { MatrixMultiplyAccumulateOperandsMaskNone = 0, MatrixMultiplyAccumulateOperandsMatrixASignedComponentsINTELMask = 0x00000001, MatrixMultiplyAccumulateOperandsMatrixBSignedComponentsINTELMask = 0x00000002, MatrixMultiplyAccumulateOperandsMatrixCBFloat16INTELMask = 0x00000004, MatrixMultiplyAccumulateOperandsMatrixResultBFloat16INTELMask = 0x00000008, MatrixMultiplyAccumulateOperandsMatrixAPackedInt8INTELMask = 0x00000010, MatrixMultiplyAccumulateOperandsMatrixBPackedInt8INTELMask = 0x00000020, MatrixMultiplyAccumulateOperandsMatrixAPackedInt4INTELMask = 0x00000040, MatrixMultiplyAccumulateOperandsMatrixBPackedInt4INTELMask = 0x00000080, MatrixMultiplyAccumulateOperandsMatrixATF32INTELMask = 0x00000100, MatrixMultiplyAccumulateOperandsMatrixBTF32INTELMask = 0x00000200, MatrixMultiplyAccumulateOperandsMatrixAPackedFloat16INTELMask = 0x00000400, MatrixMultiplyAccumulateOperandsMatrixBPackedFloat16INTELMask = 0x00000800, MatrixMultiplyAccumulateOperandsMatrixAPackedBFloat16INTELMask = 0x00001000, MatrixMultiplyAccumulateOperandsMatrixBPackedBFloat16INTELMask = 0x00002000, }; enum RawAccessChainOperandsShift { RawAccessChainOperandsRobustnessPerComponentNVShift = 0, RawAccessChainOperandsRobustnessPerElementNVShift = 1, RawAccessChainOperandsMax = 0x7fffffff, }; enum RawAccessChainOperandsMask { RawAccessChainOperandsMaskNone = 0, RawAccessChainOperandsRobustnessPerComponentNVMask = 0x00000001, RawAccessChainOperandsRobustnessPerElementNVMask = 0x00000002, }; enum FPEncoding { FPEncodingBFloat16KHR = 0, FPEncodingFloat8E4M3EXT = 4214, FPEncodingFloat8E5M2EXT = 4215, FPEncodingMax = 0x7fffffff, }; enum CooperativeVectorMatrixLayout { CooperativeVectorMatrixLayoutRowMajorNV = 0, CooperativeVectorMatrixLayoutColumnMajorNV = 1, CooperativeVectorMatrixLayoutInferencingOptimalNV = 2, CooperativeVectorMatrixLayoutTrainingOptimalNV = 3, CooperativeVectorMatrixLayoutMax = 0x7fffffff, }; enum ComponentType { ComponentTypeFloat16NV = 0, ComponentTypeFloat32NV = 1, ComponentTypeFloat64NV = 2, ComponentTypeSignedInt8NV = 3, ComponentTypeSignedInt16NV = 4, ComponentTypeSignedInt32NV = 5, ComponentTypeSignedInt64NV = 6, ComponentTypeUnsignedInt8NV = 7, ComponentTypeUnsignedInt16NV = 8, ComponentTypeUnsignedInt32NV = 9, ComponentTypeUnsignedInt64NV = 10, ComponentTypeSignedInt8PackedNV = 1000491000, ComponentTypeUnsignedInt8PackedNV = 1000491001, ComponentTypeFloatE4M3NV = 1000491002, ComponentTypeFloatE5M2NV = 1000491003, ComponentTypeMax = 0x7fffffff, }; enum Op { OpNop = 0, OpUndef = 1, OpSourceContinued = 2, OpSource = 3, OpSourceExtension = 4, OpName = 5, OpMemberName = 6, OpString = 7, OpLine = 8, OpExtension = 10, OpExtInstImport = 11, OpExtInst = 12, OpMemoryModel = 14, OpEntryPoint = 15, OpExecutionMode = 16, OpCapability = 17, OpTypeVoid = 19, OpTypeBool = 20, OpTypeInt = 21, OpTypeFloat = 22, OpTypeVector = 23, OpTypeMatrix = 24, OpTypeImage = 25, OpTypeSampler = 26, OpTypeSampledImage = 27, OpTypeArray = 28, OpTypeRuntimeArray = 29, OpTypeStruct = 30, OpTypeOpaque = 31, OpTypePointer = 32, OpTypeFunction = 33, OpTypeEvent = 34, OpTypeDeviceEvent = 35, OpTypeReserveId = 36, OpTypeQueue = 37, OpTypePipe = 38, OpTypeForwardPointer = 39, OpConstantTrue = 41, OpConstantFalse = 42, OpConstant = 43, OpConstantComposite = 44, OpConstantSampler = 45, OpConstantNull = 46, OpSpecConstantTrue = 48, OpSpecConstantFalse = 49, OpSpecConstant = 50, OpSpecConstantComposite = 51, OpSpecConstantOp = 52, OpFunction = 54, OpFunctionParameter = 55, OpFunctionEnd = 56, OpFunctionCall = 57, OpVariable = 59, OpImageTexelPointer = 60, OpLoad = 61, OpStore = 62, OpCopyMemory = 63, OpCopyMemorySized = 64, OpAccessChain = 65, OpInBoundsAccessChain = 66, OpPtrAccessChain = 67, OpArrayLength = 68, OpGenericPtrMemSemantics = 69, OpInBoundsPtrAccessChain = 70, OpDecorate = 71, OpMemberDecorate = 72, OpDecorationGroup = 73, OpGroupDecorate = 74, OpGroupMemberDecorate = 75, OpVectorExtractDynamic = 77, OpVectorInsertDynamic = 78, OpVectorShuffle = 79, OpCompositeConstruct = 80, OpCompositeExtract = 81, OpCompositeInsert = 82, OpCopyObject = 83, OpTranspose = 84, OpSampledImage = 86, OpImageSampleImplicitLod = 87, OpImageSampleExplicitLod = 88, OpImageSampleDrefImplicitLod = 89, OpImageSampleDrefExplicitLod = 90, OpImageSampleProjImplicitLod = 91, OpImageSampleProjExplicitLod = 92, OpImageSampleProjDrefImplicitLod = 93, OpImageSampleProjDrefExplicitLod = 94, OpImageFetch = 95, OpImageGather = 96, OpImageDrefGather = 97, OpImageRead = 98, OpImageWrite = 99, OpImage = 100, OpImageQueryFormat = 101, OpImageQueryOrder = 102, OpImageQuerySizeLod = 103, OpImageQuerySize = 104, OpImageQueryLod = 105, OpImageQueryLevels = 106, OpImageQuerySamples = 107, OpConvertFToU = 109, OpConvertFToS = 110, OpConvertSToF = 111, OpConvertUToF = 112, OpUConvert = 113, OpSConvert = 114, OpFConvert = 115, OpQuantizeToF16 = 116, OpConvertPtrToU = 117, OpSatConvertSToU = 118, OpSatConvertUToS = 119, OpConvertUToPtr = 120, OpPtrCastToGeneric = 121, OpGenericCastToPtr = 122, OpGenericCastToPtrExplicit = 123, OpBitcast = 124, OpSNegate = 126, OpFNegate = 127, OpIAdd = 128, OpFAdd = 129, OpISub = 130, OpFSub = 131, OpIMul = 132, OpFMul = 133, OpUDiv = 134, OpSDiv = 135, OpFDiv = 136, OpUMod = 137, OpSRem = 138, OpSMod = 139, OpFRem = 140, OpFMod = 141, OpVectorTimesScalar = 142, OpMatrixTimesScalar = 143, OpVectorTimesMatrix = 144, OpMatrixTimesVector = 145, OpMatrixTimesMatrix = 146, OpOuterProduct = 147, OpDot = 148, OpIAddCarry = 149, OpISubBorrow = 150, OpUMulExtended = 151, OpSMulExtended = 152, OpAny = 154, OpAll = 155, OpIsNan = 156, OpIsInf = 157, OpIsFinite = 158, OpIsNormal = 159, OpSignBitSet = 160, OpLessOrGreater = 161, OpOrdered = 162, OpUnordered = 163, OpLogicalEqual = 164, OpLogicalNotEqual = 165, OpLogicalOr = 166, OpLogicalAnd = 167, OpLogicalNot = 168, OpSelect = 169, OpIEqual = 170, OpINotEqual = 171, OpUGreaterThan = 172, OpSGreaterThan = 173, OpUGreaterThanEqual = 174, OpSGreaterThanEqual = 175, OpULessThan = 176, OpSLessThan = 177, OpULessThanEqual = 178, OpSLessThanEqual = 179, OpFOrdEqual = 180, OpFUnordEqual = 181, OpFOrdNotEqual = 182, OpFUnordNotEqual = 183, OpFOrdLessThan = 184, OpFUnordLessThan = 185, OpFOrdGreaterThan = 186, OpFUnordGreaterThan = 187, OpFOrdLessThanEqual = 188, OpFUnordLessThanEqual = 189, OpFOrdGreaterThanEqual = 190, OpFUnordGreaterThanEqual = 191, OpShiftRightLogical = 194, OpShiftRightArithmetic = 195, OpShiftLeftLogical = 196, OpBitwiseOr = 197, OpBitwiseXor = 198, OpBitwiseAnd = 199, OpNot = 200, OpBitFieldInsert = 201, OpBitFieldSExtract = 202, OpBitFieldUExtract = 203, OpBitReverse = 204, OpBitCount = 205, OpDPdx = 207, OpDPdy = 208, OpFwidth = 209, OpDPdxFine = 210, OpDPdyFine = 211, OpFwidthFine = 212, OpDPdxCoarse = 213, OpDPdyCoarse = 214, OpFwidthCoarse = 215, OpEmitVertex = 218, OpEndPrimitive = 219, OpEmitStreamVertex = 220, OpEndStreamPrimitive = 221, OpControlBarrier = 224, OpMemoryBarrier = 225, OpAtomicLoad = 227, OpAtomicStore = 228, OpAtomicExchange = 229, OpAtomicCompareExchange = 230, OpAtomicCompareExchangeWeak = 231, OpAtomicIIncrement = 232, OpAtomicIDecrement = 233, OpAtomicIAdd = 234, OpAtomicISub = 235, OpAtomicSMin = 236, OpAtomicUMin = 237, OpAtomicSMax = 238, OpAtomicUMax = 239, OpAtomicAnd = 240, OpAtomicOr = 241, OpAtomicXor = 242, OpPhi = 245, OpLoopMerge = 246, OpSelectionMerge = 247, OpLabel = 248, OpBranch = 249, OpBranchConditional = 250, OpSwitch = 251, OpKill = 252, OpReturn = 253, OpReturnValue = 254, OpUnreachable = 255, OpLifetimeStart = 256, OpLifetimeStop = 257, OpGroupAsyncCopy = 259, OpGroupWaitEvents = 260, OpGroupAll = 261, OpGroupAny = 262, OpGroupBroadcast = 263, OpGroupIAdd = 264, OpGroupFAdd = 265, OpGroupFMin = 266, OpGroupUMin = 267, OpGroupSMin = 268, OpGroupFMax = 269, OpGroupUMax = 270, OpGroupSMax = 271, OpReadPipe = 274, OpWritePipe = 275, OpReservedReadPipe = 276, OpReservedWritePipe = 277, OpReserveReadPipePackets = 278, OpReserveWritePipePackets = 279, OpCommitReadPipe = 280, OpCommitWritePipe = 281, OpIsValidReserveId = 282, OpGetNumPipePackets = 283, OpGetMaxPipePackets = 284, OpGroupReserveReadPipePackets = 285, OpGroupReserveWritePipePackets = 286, OpGroupCommitReadPipe = 287, OpGroupCommitWritePipe = 288, OpEnqueueMarker = 291, OpEnqueueKernel = 292, OpGetKernelNDrangeSubGroupCount = 293, OpGetKernelNDrangeMaxSubGroupSize = 294, OpGetKernelWorkGroupSize = 295, OpGetKernelPreferredWorkGroupSizeMultiple = 296, OpRetainEvent = 297, OpReleaseEvent = 298, OpCreateUserEvent = 299, OpIsValidEvent = 300, OpSetUserEventStatus = 301, OpCaptureEventProfilingInfo = 302, OpGetDefaultQueue = 303, OpBuildNDRange = 304, OpImageSparseSampleImplicitLod = 305, OpImageSparseSampleExplicitLod = 306, OpImageSparseSampleDrefImplicitLod = 307, OpImageSparseSampleDrefExplicitLod = 308, OpImageSparseSampleProjImplicitLod = 309, OpImageSparseSampleProjExplicitLod = 310, OpImageSparseSampleProjDrefImplicitLod = 311, OpImageSparseSampleProjDrefExplicitLod = 312, OpImageSparseFetch = 313, OpImageSparseGather = 314, OpImageSparseDrefGather = 315, OpImageSparseTexelsResident = 316, OpNoLine = 317, OpAtomicFlagTestAndSet = 318, OpAtomicFlagClear = 319, OpImageSparseRead = 320, OpSizeOf = 321, OpTypePipeStorage = 322, OpConstantPipeStorage = 323, OpCreatePipeFromPipeStorage = 324, OpGetKernelLocalSizeForSubgroupCount = 325, OpGetKernelMaxNumSubgroups = 326, OpTypeNamedBarrier = 327, OpNamedBarrierInitialize = 328, OpMemoryNamedBarrier = 329, OpModuleProcessed = 330, OpExecutionModeId = 331, OpDecorateId = 332, OpGroupNonUniformElect = 333, OpGroupNonUniformAll = 334, OpGroupNonUniformAny = 335, OpGroupNonUniformAllEqual = 336, OpGroupNonUniformBroadcast = 337, OpGroupNonUniformBroadcastFirst = 338, OpGroupNonUniformBallot = 339, OpGroupNonUniformInverseBallot = 340, OpGroupNonUniformBallotBitExtract = 341, OpGroupNonUniformBallotBitCount = 342, OpGroupNonUniformBallotFindLSB = 343, OpGroupNonUniformBallotFindMSB = 344, OpGroupNonUniformShuffle = 345, OpGroupNonUniformShuffleXor = 346, OpGroupNonUniformShuffleUp = 347, OpGroupNonUniformShuffleDown = 348, OpGroupNonUniformIAdd = 349, OpGroupNonUniformFAdd = 350, OpGroupNonUniformIMul = 351, OpGroupNonUniformFMul = 352, OpGroupNonUniformSMin = 353, OpGroupNonUniformUMin = 354, OpGroupNonUniformFMin = 355, OpGroupNonUniformSMax = 356, OpGroupNonUniformUMax = 357, OpGroupNonUniformFMax = 358, OpGroupNonUniformBitwiseAnd = 359, OpGroupNonUniformBitwiseOr = 360, OpGroupNonUniformBitwiseXor = 361, OpGroupNonUniformLogicalAnd = 362, OpGroupNonUniformLogicalOr = 363, OpGroupNonUniformLogicalXor = 364, OpGroupNonUniformQuadBroadcast = 365, OpGroupNonUniformQuadSwap = 366, OpCopyLogical = 400, OpPtrEqual = 401, OpPtrNotEqual = 402, OpPtrDiff = 403, OpColorAttachmentReadEXT = 4160, OpDepthAttachmentReadEXT = 4161, OpStencilAttachmentReadEXT = 4162, OpTypeTensorARM = 4163, OpTensorReadARM = 4164, OpTensorWriteARM = 4165, OpTensorQuerySizeARM = 4166, OpGraphConstantARM = 4181, OpGraphEntryPointARM = 4182, OpGraphARM = 4183, OpGraphInputARM = 4184, OpGraphSetOutputARM = 4185, OpGraphEndARM = 4186, OpTypeGraphARM = 4190, OpTerminateInvocation = 4416, OpTypeUntypedPointerKHR = 4417, OpUntypedVariableKHR = 4418, OpUntypedAccessChainKHR = 4419, OpUntypedInBoundsAccessChainKHR = 4420, OpSubgroupBallotKHR = 4421, OpSubgroupFirstInvocationKHR = 4422, OpUntypedPtrAccessChainKHR = 4423, OpUntypedInBoundsPtrAccessChainKHR = 4424, OpUntypedArrayLengthKHR = 4425, OpUntypedPrefetchKHR = 4426, OpSubgroupAllKHR = 4428, OpSubgroupAnyKHR = 4429, OpSubgroupAllEqualKHR = 4430, OpGroupNonUniformRotateKHR = 4431, OpSubgroupReadInvocationKHR = 4432, OpExtInstWithForwardRefsKHR = 4433, OpTraceRayKHR = 4445, OpExecuteCallableKHR = 4446, OpConvertUToAccelerationStructureKHR = 4447, OpIgnoreIntersectionKHR = 4448, OpTerminateRayKHR = 4449, OpSDot = 4450, OpSDotKHR = 4450, OpUDot = 4451, OpUDotKHR = 4451, OpSUDot = 4452, OpSUDotKHR = 4452, OpSDotAccSat = 4453, OpSDotAccSatKHR = 4453, OpUDotAccSat = 4454, OpUDotAccSatKHR = 4454, OpSUDotAccSat = 4455, OpSUDotAccSatKHR = 4455, OpTypeCooperativeMatrixKHR = 4456, OpCooperativeMatrixLoadKHR = 4457, OpCooperativeMatrixStoreKHR = 4458, OpCooperativeMatrixMulAddKHR = 4459, OpCooperativeMatrixLengthKHR = 4460, OpConstantCompositeReplicateEXT = 4461, OpSpecConstantCompositeReplicateEXT = 4462, OpCompositeConstructReplicateEXT = 4463, OpTypeRayQueryKHR = 4472, OpRayQueryInitializeKHR = 4473, OpRayQueryTerminateKHR = 4474, OpRayQueryGenerateIntersectionKHR = 4475, OpRayQueryConfirmIntersectionKHR = 4476, OpRayQueryProceedKHR = 4477, OpRayQueryGetIntersectionTypeKHR = 4479, OpImageSampleWeightedQCOM = 4480, OpImageBoxFilterQCOM = 4481, OpImageBlockMatchSSDQCOM = 4482, OpImageBlockMatchSADQCOM = 4483, OpBitCastArrayQCOM = 4497, OpImageBlockMatchWindowSSDQCOM = 4500, OpImageBlockMatchWindowSADQCOM = 4501, OpImageBlockMatchGatherSSDQCOM = 4502, OpImageBlockMatchGatherSADQCOM = 4503, OpCompositeConstructCoopMatQCOM = 4540, OpCompositeExtractCoopMatQCOM = 4541, OpExtractSubArrayQCOM = 4542, OpGroupIAddNonUniformAMD = 5000, OpGroupFAddNonUniformAMD = 5001, OpGroupFMinNonUniformAMD = 5002, OpGroupUMinNonUniformAMD = 5003, OpGroupSMinNonUniformAMD = 5004, OpGroupFMaxNonUniformAMD = 5005, OpGroupUMaxNonUniformAMD = 5006, OpGroupSMaxNonUniformAMD = 5007, OpFragmentMaskFetchAMD = 5011, OpFragmentFetchAMD = 5012, OpReadClockKHR = 5056, OpAllocateNodePayloadsAMDX = 5074, OpEnqueueNodePayloadsAMDX = 5075, OpTypeNodePayloadArrayAMDX = 5076, OpFinishWritingNodePayloadAMDX = 5078, OpNodePayloadArrayLengthAMDX = 5090, OpIsNodePayloadValidAMDX = 5101, OpConstantStringAMDX = 5103, OpSpecConstantStringAMDX = 5104, OpGroupNonUniformQuadAllKHR = 5110, OpGroupNonUniformQuadAnyKHR = 5111, OpHitObjectRecordHitMotionNV = 5249, OpHitObjectRecordHitWithIndexMotionNV = 5250, OpHitObjectRecordMissMotionNV = 5251, OpHitObjectGetWorldToObjectNV = 5252, OpHitObjectGetObjectToWorldNV = 5253, OpHitObjectGetObjectRayDirectionNV = 5254, OpHitObjectGetObjectRayOriginNV = 5255, OpHitObjectTraceRayMotionNV = 5256, OpHitObjectGetShaderRecordBufferHandleNV = 5257, OpHitObjectGetShaderBindingTableRecordIndexNV = 5258, OpHitObjectRecordEmptyNV = 5259, OpHitObjectTraceRayNV = 5260, OpHitObjectRecordHitNV = 5261, OpHitObjectRecordHitWithIndexNV = 5262, OpHitObjectRecordMissNV = 5263, OpHitObjectExecuteShaderNV = 5264, OpHitObjectGetCurrentTimeNV = 5265, OpHitObjectGetAttributesNV = 5266, OpHitObjectGetHitKindNV = 5267, OpHitObjectGetPrimitiveIndexNV = 5268, OpHitObjectGetGeometryIndexNV = 5269, OpHitObjectGetInstanceIdNV = 5270, OpHitObjectGetInstanceCustomIndexNV = 5271, OpHitObjectGetWorldRayDirectionNV = 5272, OpHitObjectGetWorldRayOriginNV = 5273, OpHitObjectGetRayTMaxNV = 5274, OpHitObjectGetRayTMinNV = 5275, OpHitObjectIsEmptyNV = 5276, OpHitObjectIsHitNV = 5277, OpHitObjectIsMissNV = 5278, OpReorderThreadWithHitObjectNV = 5279, OpReorderThreadWithHintNV = 5280, OpTypeHitObjectNV = 5281, OpImageSampleFootprintNV = 5283, OpTypeCooperativeVectorNV = 5288, OpCooperativeVectorMatrixMulNV = 5289, OpCooperativeVectorOuterProductAccumulateNV = 5290, OpCooperativeVectorReduceSumAccumulateNV = 5291, OpCooperativeVectorMatrixMulAddNV = 5292, OpCooperativeMatrixConvertNV = 5293, OpEmitMeshTasksEXT = 5294, OpSetMeshOutputsEXT = 5295, OpGroupNonUniformPartitionNV = 5296, OpWritePackedPrimitiveIndices4x8NV = 5299, OpFetchMicroTriangleVertexPositionNV = 5300, OpFetchMicroTriangleVertexBarycentricNV = 5301, OpCooperativeVectorLoadNV = 5302, OpCooperativeVectorStoreNV = 5303, OpReportIntersectionKHR = 5334, OpReportIntersectionNV = 5334, OpIgnoreIntersectionNV = 5335, OpTerminateRayNV = 5336, OpTraceNV = 5337, OpTraceMotionNV = 5338, OpTraceRayMotionNV = 5339, OpRayQueryGetIntersectionTriangleVertexPositionsKHR = 5340, OpTypeAccelerationStructureKHR = 5341, OpTypeAccelerationStructureNV = 5341, OpExecuteCallableNV = 5344, OpRayQueryGetClusterIdNV = 5345, OpHitObjectGetClusterIdNV = 5346, OpTypeCooperativeMatrixNV = 5358, OpCooperativeMatrixLoadNV = 5359, OpCooperativeMatrixStoreNV = 5360, OpCooperativeMatrixMulAddNV = 5361, OpCooperativeMatrixLengthNV = 5362, OpBeginInvocationInterlockEXT = 5364, OpEndInvocationInterlockEXT = 5365, OpCooperativeMatrixReduceNV = 5366, OpCooperativeMatrixLoadTensorNV = 5367, OpCooperativeMatrixStoreTensorNV = 5368, OpCooperativeMatrixPerElementOpNV = 5369, OpTypeTensorLayoutNV = 5370, OpTypeTensorViewNV = 5371, OpCreateTensorLayoutNV = 5372, OpTensorLayoutSetDimensionNV = 5373, OpTensorLayoutSetStrideNV = 5374, OpTensorLayoutSliceNV = 5375, OpTensorLayoutSetClampValueNV = 5376, OpCreateTensorViewNV = 5377, OpTensorViewSetDimensionNV = 5378, OpTensorViewSetStrideNV = 5379, OpDemoteToHelperInvocation = 5380, OpDemoteToHelperInvocationEXT = 5380, OpIsHelperInvocationEXT = 5381, OpTensorViewSetClipNV = 5382, OpTensorLayoutSetBlockSizeNV = 5384, OpCooperativeMatrixTransposeNV = 5390, OpConvertUToImageNV = 5391, OpConvertUToSamplerNV = 5392, OpConvertImageToUNV = 5393, OpConvertSamplerToUNV = 5394, OpConvertUToSampledImageNV = 5395, OpConvertSampledImageToUNV = 5396, OpSamplerImageAddressingModeNV = 5397, OpRawAccessChainNV = 5398, OpRayQueryGetIntersectionSpherePositionNV = 5427, OpRayQueryGetIntersectionSphereRadiusNV = 5428, OpRayQueryGetIntersectionLSSPositionsNV = 5429, OpRayQueryGetIntersectionLSSRadiiNV = 5430, OpRayQueryGetIntersectionLSSHitValueNV = 5431, OpHitObjectGetSpherePositionNV = 5432, OpHitObjectGetSphereRadiusNV = 5433, OpHitObjectGetLSSPositionsNV = 5434, OpHitObjectGetLSSRadiiNV = 5435, OpHitObjectIsSphereHitNV = 5436, OpHitObjectIsLSSHitNV = 5437, OpRayQueryIsSphereHitNV = 5438, OpRayQueryIsLSSHitNV = 5439, OpSubgroupShuffleINTEL = 5571, OpSubgroupShuffleDownINTEL = 5572, OpSubgroupShuffleUpINTEL = 5573, OpSubgroupShuffleXorINTEL = 5574, OpSubgroupBlockReadINTEL = 5575, OpSubgroupBlockWriteINTEL = 5576, OpSubgroupImageBlockReadINTEL = 5577, OpSubgroupImageBlockWriteINTEL = 5578, OpSubgroupImageMediaBlockReadINTEL = 5580, OpSubgroupImageMediaBlockWriteINTEL = 5581, OpUCountLeadingZerosINTEL = 5585, OpUCountTrailingZerosINTEL = 5586, OpAbsISubINTEL = 5587, OpAbsUSubINTEL = 5588, OpIAddSatINTEL = 5589, OpUAddSatINTEL = 5590, OpIAverageINTEL = 5591, OpUAverageINTEL = 5592, OpIAverageRoundedINTEL = 5593, OpUAverageRoundedINTEL = 5594, OpISubSatINTEL = 5595, OpUSubSatINTEL = 5596, OpIMul32x16INTEL = 5597, OpUMul32x16INTEL = 5598, OpConstantFunctionPointerINTEL = 5600, OpFunctionPointerCallINTEL = 5601, OpAsmTargetINTEL = 5609, OpAsmINTEL = 5610, OpAsmCallINTEL = 5611, OpAtomicFMinEXT = 5614, OpAtomicFMaxEXT = 5615, OpAssumeTrueKHR = 5630, OpExpectKHR = 5631, OpDecorateString = 5632, OpDecorateStringGOOGLE = 5632, OpMemberDecorateString = 5633, OpMemberDecorateStringGOOGLE = 5633, OpVmeImageINTEL = 5699, OpTypeVmeImageINTEL = 5700, OpTypeAvcImePayloadINTEL = 5701, OpTypeAvcRefPayloadINTEL = 5702, OpTypeAvcSicPayloadINTEL = 5703, OpTypeAvcMcePayloadINTEL = 5704, OpTypeAvcMceResultINTEL = 5705, OpTypeAvcImeResultINTEL = 5706, OpTypeAvcImeResultSingleReferenceStreamoutINTEL = 5707, OpTypeAvcImeResultDualReferenceStreamoutINTEL = 5708, OpTypeAvcImeSingleReferenceStreaminINTEL = 5709, OpTypeAvcImeDualReferenceStreaminINTEL = 5710, OpTypeAvcRefResultINTEL = 5711, OpTypeAvcSicResultINTEL = 5712, OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL = 5713, OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL = 5714, OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL = 5715, OpSubgroupAvcMceSetInterShapePenaltyINTEL = 5716, OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL = 5717, OpSubgroupAvcMceSetInterDirectionPenaltyINTEL = 5718, OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL = 5719, OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL = 5720, OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL = 5721, OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL = 5722, OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL = 5723, OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL = 5724, OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL = 5725, OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL = 5726, OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL = 5727, OpSubgroupAvcMceSetAcOnlyHaarINTEL = 5728, OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL = 5729, OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL = 5730, OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL = 5731, OpSubgroupAvcMceConvertToImePayloadINTEL = 5732, OpSubgroupAvcMceConvertToImeResultINTEL = 5733, OpSubgroupAvcMceConvertToRefPayloadINTEL = 5734, OpSubgroupAvcMceConvertToRefResultINTEL = 5735, OpSubgroupAvcMceConvertToSicPayloadINTEL = 5736, OpSubgroupAvcMceConvertToSicResultINTEL = 5737, OpSubgroupAvcMceGetMotionVectorsINTEL = 5738, OpSubgroupAvcMceGetInterDistortionsINTEL = 5739, OpSubgroupAvcMceGetBestInterDistortionsINTEL = 5740, OpSubgroupAvcMceGetInterMajorShapeINTEL = 5741, OpSubgroupAvcMceGetInterMinorShapeINTEL = 5742, OpSubgroupAvcMceGetInterDirectionsINTEL = 5743, OpSubgroupAvcMceGetInterMotionVectorCountINTEL = 5744, OpSubgroupAvcMceGetInterReferenceIdsINTEL = 5745, OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL = 5746, OpSubgroupAvcImeInitializeINTEL = 5747, OpSubgroupAvcImeSetSingleReferenceINTEL = 5748, OpSubgroupAvcImeSetDualReferenceINTEL = 5749, OpSubgroupAvcImeRefWindowSizeINTEL = 5750, OpSubgroupAvcImeAdjustRefOffsetINTEL = 5751, OpSubgroupAvcImeConvertToMcePayloadINTEL = 5752, OpSubgroupAvcImeSetMaxMotionVectorCountINTEL = 5753, OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL = 5754, OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL = 5755, OpSubgroupAvcImeSetWeightedSadINTEL = 5756, OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL = 5757, OpSubgroupAvcImeEvaluateWithDualReferenceINTEL = 5758, OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL = 5759, OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL = 5760, OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL = 5761, OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL = 5762, OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL = 5763, OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL = 5764, OpSubgroupAvcImeConvertToMceResultINTEL = 5765, OpSubgroupAvcImeGetSingleReferenceStreaminINTEL = 5766, OpSubgroupAvcImeGetDualReferenceStreaminINTEL = 5767, OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL = 5768, OpSubgroupAvcImeStripDualReferenceStreamoutINTEL = 5769, OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL = 5770, OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL = 5771, OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL = 5772, OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL = 5773, OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL = 5774, OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL = 5775, OpSubgroupAvcImeGetBorderReachedINTEL = 5776, OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL = 5777, OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL = 5778, OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL = 5779, OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL = 5780, OpSubgroupAvcFmeInitializeINTEL = 5781, OpSubgroupAvcBmeInitializeINTEL = 5782, OpSubgroupAvcRefConvertToMcePayloadINTEL = 5783, OpSubgroupAvcRefSetBidirectionalMixDisableINTEL = 5784, OpSubgroupAvcRefSetBilinearFilterEnableINTEL = 5785, OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL = 5786, OpSubgroupAvcRefEvaluateWithDualReferenceINTEL = 5787, OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL = 5788, OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL = 5789, OpSubgroupAvcRefConvertToMceResultINTEL = 5790, OpSubgroupAvcSicInitializeINTEL = 5791, OpSubgroupAvcSicConfigureSkcINTEL = 5792, OpSubgroupAvcSicConfigureIpeLumaINTEL = 5793, OpSubgroupAvcSicConfigureIpeLumaChromaINTEL = 5794, OpSubgroupAvcSicGetMotionVectorMaskINTEL = 5795, OpSubgroupAvcSicConvertToMcePayloadINTEL = 5796, OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL = 5797, OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL = 5798, OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL = 5799, OpSubgroupAvcSicSetBilinearFilterEnableINTEL = 5800, OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL = 5801, OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL = 5802, OpSubgroupAvcSicEvaluateIpeINTEL = 5803, OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL = 5804, OpSubgroupAvcSicEvaluateWithDualReferenceINTEL = 5805, OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL = 5806, OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL = 5807, OpSubgroupAvcSicConvertToMceResultINTEL = 5808, OpSubgroupAvcSicGetIpeLumaShapeINTEL = 5809, OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL = 5810, OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL = 5811, OpSubgroupAvcSicGetPackedIpeLumaModesINTEL = 5812, OpSubgroupAvcSicGetIpeChromaModeINTEL = 5813, OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL = 5814, OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL = 5815, OpSubgroupAvcSicGetInterRawSadsINTEL = 5816, OpVariableLengthArrayINTEL = 5818, OpSaveMemoryINTEL = 5819, OpRestoreMemoryINTEL = 5820, OpArbitraryFloatSinCosPiINTEL = 5840, OpArbitraryFloatCastINTEL = 5841, OpArbitraryFloatCastFromIntINTEL = 5842, OpArbitraryFloatCastToIntINTEL = 5843, OpArbitraryFloatAddINTEL = 5846, OpArbitraryFloatSubINTEL = 5847, OpArbitraryFloatMulINTEL = 5848, OpArbitraryFloatDivINTEL = 5849, OpArbitraryFloatGTINTEL = 5850, OpArbitraryFloatGEINTEL = 5851, OpArbitraryFloatLTINTEL = 5852, OpArbitraryFloatLEINTEL = 5853, OpArbitraryFloatEQINTEL = 5854, OpArbitraryFloatRecipINTEL = 5855, OpArbitraryFloatRSqrtINTEL = 5856, OpArbitraryFloatCbrtINTEL = 5857, OpArbitraryFloatHypotINTEL = 5858, OpArbitraryFloatSqrtINTEL = 5859, OpArbitraryFloatLogINTEL = 5860, OpArbitraryFloatLog2INTEL = 5861, OpArbitraryFloatLog10INTEL = 5862, OpArbitraryFloatLog1pINTEL = 5863, OpArbitraryFloatExpINTEL = 5864, OpArbitraryFloatExp2INTEL = 5865, OpArbitraryFloatExp10INTEL = 5866, OpArbitraryFloatExpm1INTEL = 5867, OpArbitraryFloatSinINTEL = 5868, OpArbitraryFloatCosINTEL = 5869, OpArbitraryFloatSinCosINTEL = 5870, OpArbitraryFloatSinPiINTEL = 5871, OpArbitraryFloatCosPiINTEL = 5872, OpArbitraryFloatASinINTEL = 5873, OpArbitraryFloatASinPiINTEL = 5874, OpArbitraryFloatACosINTEL = 5875, OpArbitraryFloatACosPiINTEL = 5876, OpArbitraryFloatATanINTEL = 5877, OpArbitraryFloatATanPiINTEL = 5878, OpArbitraryFloatATan2INTEL = 5879, OpArbitraryFloatPowINTEL = 5880, OpArbitraryFloatPowRINTEL = 5881, OpArbitraryFloatPowNINTEL = 5882, OpLoopControlINTEL = 5887, OpAliasDomainDeclINTEL = 5911, OpAliasScopeDeclINTEL = 5912, OpAliasScopeListDeclINTEL = 5913, OpFixedSqrtINTEL = 5923, OpFixedRecipINTEL = 5924, OpFixedRsqrtINTEL = 5925, OpFixedSinINTEL = 5926, OpFixedCosINTEL = 5927, OpFixedSinCosINTEL = 5928, OpFixedSinPiINTEL = 5929, OpFixedCosPiINTEL = 5930, OpFixedSinCosPiINTEL = 5931, OpFixedLogINTEL = 5932, OpFixedExpINTEL = 5933, OpPtrCastToCrossWorkgroupINTEL = 5934, OpCrossWorkgroupCastToPtrINTEL = 5938, OpReadPipeBlockingINTEL = 5946, OpWritePipeBlockingINTEL = 5947, OpFPGARegINTEL = 5949, OpRayQueryGetRayTMinKHR = 6016, OpRayQueryGetRayFlagsKHR = 6017, OpRayQueryGetIntersectionTKHR = 6018, OpRayQueryGetIntersectionInstanceCustomIndexKHR = 6019, OpRayQueryGetIntersectionInstanceIdKHR = 6020, OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR = 6021, OpRayQueryGetIntersectionGeometryIndexKHR = 6022, OpRayQueryGetIntersectionPrimitiveIndexKHR = 6023, OpRayQueryGetIntersectionBarycentricsKHR = 6024, OpRayQueryGetIntersectionFrontFaceKHR = 6025, OpRayQueryGetIntersectionCandidateAABBOpaqueKHR = 6026, OpRayQueryGetIntersectionObjectRayDirectionKHR = 6027, OpRayQueryGetIntersectionObjectRayOriginKHR = 6028, OpRayQueryGetWorldRayDirectionKHR = 6029, OpRayQueryGetWorldRayOriginKHR = 6030, OpRayQueryGetIntersectionObjectToWorldKHR = 6031, OpRayQueryGetIntersectionWorldToObjectKHR = 6032, OpAtomicFAddEXT = 6035, OpTypeBufferSurfaceINTEL = 6086, OpTypeStructContinuedINTEL = 6090, OpConstantCompositeContinuedINTEL = 6091, OpSpecConstantCompositeContinuedINTEL = 6092, OpCompositeConstructContinuedINTEL = 6096, OpConvertFToBF16INTEL = 6116, OpConvertBF16ToFINTEL = 6117, OpControlBarrierArriveINTEL = 6142, OpControlBarrierWaitINTEL = 6143, OpArithmeticFenceEXT = 6145, OpTaskSequenceCreateINTEL = 6163, OpTaskSequenceAsyncINTEL = 6164, OpTaskSequenceGetINTEL = 6165, OpTaskSequenceReleaseINTEL = 6166, OpTypeTaskSequenceINTEL = 6199, OpSubgroupBlockPrefetchINTEL = 6221, OpSubgroup2DBlockLoadINTEL = 6231, OpSubgroup2DBlockLoadTransformINTEL = 6232, OpSubgroup2DBlockLoadTransposeINTEL = 6233, OpSubgroup2DBlockPrefetchINTEL = 6234, OpSubgroup2DBlockStoreINTEL = 6235, OpSubgroupMatrixMultiplyAccumulateINTEL = 6237, OpBitwiseFunctionINTEL = 6242, OpConditionalExtensionINTEL = 6248, OpConditionalEntryPointINTEL = 6249, OpConditionalCapabilityINTEL = 6250, OpSpecConstantTargetINTEL = 6251, OpSpecConstantArchitectureINTEL = 6252, OpSpecConstantCapabilitiesINTEL = 6253, OpConditionalCopyObjectINTEL = 6254, OpGroupIMulKHR = 6401, OpGroupFMulKHR = 6402, OpGroupBitwiseAndKHR = 6403, OpGroupBitwiseOrKHR = 6404, OpGroupBitwiseXorKHR = 6405, OpGroupLogicalAndKHR = 6406, OpGroupLogicalOrKHR = 6407, OpGroupLogicalXorKHR = 6408, OpRoundFToTF32INTEL = 6426, OpMaskedGatherINTEL = 6428, OpMaskedScatterINTEL = 6429, OpConvertHandleToImageINTEL = 6529, OpConvertHandleToSamplerINTEL = 6530, OpConvertHandleToSampledImageINTEL = 6531, OpMax = 0x7fffffff, }; #line 5327 "C:/Users/Rynair/Desktop/Nabla/3rdparty/dxc/dxc/external/SPIRV-Headers/include/spirv/unified1/spirv.hpp" } // end namespace spv #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/type_traits.hlsl" // Copyright (C) 2022 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts.hlsl" // Copyright (C) 2023-2024 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts/vector.hlsl" // Copyright (C) 2024-2025 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts.hlsl" // Copyright (C) 2023-2024 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts/core.hlsl" // Copyright (C) 2024-2025 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/type_traits.hlsl" // Copyright (C) 2022 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 13 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts/vector.hlsl" namespace nbl { namespace hlsl { namespace concepts { //! Concept for native vectors. template<typename T> const static bool Vector = is_vector<T>::value; template<typename T> const static bool FloatingPointVector = concepts::Vector<T> && concepts::FloatingPointScalar<typename vector_traits<T>::scalar_type>; template<typename T> const static bool IntVector = concepts::Vector<T> && (is_integral_v<typename vector_traits<T>::scalar_type>); template<typename T> const static bool SignedIntVector = concepts::Vector<T> && concepts::SignedIntegralScalar<typename vector_traits<T>::scalar_type>; //! Concept for native vectors and vector like structs. template<typename T> const static bool Vectorial = vector_traits<T>::IsVector; #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts/__end.hlsl" // Copyright (C) 2023-2024 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 36 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts/vector.hlsl" template<typename T> const static bool FloatingPointVectorial = concepts::Vectorial<T> && concepts::FloatingPointScalar<typename vector_traits<T>::scalar_type>; template<typename T> const static bool FloatingPointLikeVectorial = concepts::Vectorial<T> && concepts::FloatingPointLikeScalar<typename vector_traits<T>::scalar_type>; template<typename T> const static bool IntVectorial = concepts::Vectorial<T> && (is_integral_v<typename vector_traits<T>::scalar_type>); template<typename T> const static bool IntegralLikeVectorial = concepts::Vectorial<T> && concepts::IntegralLikeScalar<typename vector_traits<T>::scalar_type>; template<typename T> const static bool SignedIntVectorial = concepts::Vectorial<T> && concepts::SignedIntegralScalar<typename vector_traits<T>::scalar_type>; } template<typename Vectorial> struct extent<Vectorial, 0 ,::nbl::hlsl::enable_if_t<(concepts::Vectorial<Vectorial>),void> > : integral_constant<uint64_t, vector_traits<Vectorial>::Dimension> {}; } } #line 17 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/spirv_intrinsics/core.hlsl" namespace nbl { namespace hlsl { #line 31 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/spirv_intrinsics/core.hlsl" // TODO: some poor soul needs to study rest of https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#_capability #line 34 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/spirv_intrinsics/core.hlsl" // there's a whole lot more of them #line 49 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/spirv_intrinsics/core.hlsl" // 1.6 core caps // UniformDecoration // Demote to helper invocation // Some integer dot product stuff // #line 61 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/spirv_intrinsics/core.hlsl" namespace spirv { //! General [[vk::ext_builtin_input(spv::BuiltInHelperInvocation)]] static const bool HelperInvocation; //! Vertex Inputs [[vk::ext_builtin_input(spv::BuiltInVertexIndex)]] static const uint32_t VertexIndex; [[vk::ext_builtin_input(spv::BuiltInInstanceIndex)]] static const uint32_t InstanceIndex; //! Vertex and friends [[vk::ext_builtin_output(spv::BuiltInPosition)]] static float32_t4 Position; //! Compute Shader Builtins [[vk::ext_builtin_input(spv::BuiltInNumWorkgroups)]] static const uint32_t3 NumWorkGroups; // TODO: Doesn't work, find out why and file issue on DXC! //[[vk::ext_builtin_input(spv::BuiltInWorkgroupSize)]] //static const uint32_t3 WorkgroupSize; [[vk::ext_builtin_input(spv::BuiltInWorkgroupId)]] static const uint32_t3 WorkgroupId; [[vk::ext_builtin_input(spv::BuiltInLocalInvocationId)]] static const uint32_t3 LocalInvocationId; [[vk::ext_builtin_input(spv::BuiltInGlobalInvocationId)]] static const uint32_t3 GlobalInvocationId; [[vk::ext_builtin_input(spv::BuiltInLocalInvocationIndex)]] static const uint32_t LocalInvocationIndex; //! General Types template<uint32_t StorageClass, typename T> using pointer_t = vk::SpirvOpaqueType<spv::OpTypePointer,vk::Literal<vk::integral_constant<uint32_t,StorageClass> >,T>; template<typename T> struct is_pointer : false_type {}; template<typename I, I StorageClass, typename TT> struct is_pointer<vk::SpirvOpaqueType<spv::OpTypePointer,vk::Literal<vk::integral_constant<I,StorageClass> >,TT> > : is_integral<I> {}; template<uint32_t Size, uint32_t Alignment, typename I, I StorageClass, typename TT> struct is_pointer<vk::SpirvType<spv::OpTypePointer,Size,Alignment,vk::Literal<vk::integral_constant<I,StorageClass> >,TT> > : is_integral<I> {}; template<class T> const static bool is_pointer_v = is_pointer<T>::value; template<typename T> using bda_pointer_t [[vk::ext_capability(spv::CapabilityPhysicalStorageBufferAddresses)]] = vk::SpirvType<spv::OpTypePointer, sizeof(uint64_t),alignment_of_v<uint64_t>, vk::Literal<vk::integral_constant<uint32_t, spv::StorageClassPhysicalStorageBuffer> >, T>; template<typename T> struct is_bda_pointer : false_type {}; template<typename I, typename TT> 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> {}; template<class T> const static bool is_bda_pointer_v = is_bda_pointer<T>::value; //! General Operations //! Miscellaneous Instructions template<typename T> [[vk::ext_instruction(spv::OpUndef)]] T undef(); // template<typename M, typename T> [[vk::ext_instruction(spv::OpAccessChain)]] bda_pointer_t<M> accessChain(bda_pointer_t<T> v, int32_t index); template<typename M, uint32_t StorageClass, typename T> [[vk::ext_instruction(spv::OpAccessChain)]] pointer_t<StorageClass,M> accessChain(pointer_t<StorageClass,T> v, int32_t index); // The holy operation that makes addrof possible template<typename T, typename U> [[vk::ext_instruction(spv::OpCopyObject)]] T copyObject(U v); // unfortunately without reflection we can't validate that objects "logically match" in a concept template<typename T, typename U> [[vk::ext_instruction(spv::OpCopyLogical)]] enable_if_t<!is_same_v<T,U>,T> copyLogical([[vk::ext_reference]] U v); template<typename T, typename Ptr_U> [[vk::ext_instruction(spv::OpCopyLogical)]] enable_if_t<is_pointer_v<Ptr_U>/* && !is_same_v<T,U>*/,T> copyLogical(Ptr_U v); // Here's the thing with atomics, it's not only the data type that dictates whether you can do an atomic or not. // It's the storage class that has the most effect (shared vs storage vs image) and we can't check that easily template<typename T> // integers operate on 2s complement so same op for signed and unsigned [[vk::ext_instruction(spv::OpAtomicIAdd)]] enable_if_t<is_same_v<T,uint32_t> || is_same_v<T,int32_t>, T> atomicIAdd([[vk::ext_reference]] T ptr, uint32_t memoryScope, uint32_t memorySemantics, T value); template<typename T, typename Ptr_T> // DXC Workaround [[vk::ext_instruction(spv::OpAtomicIAdd)]] 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); template<typename T> // integers operate on 2s complement so same op for signed and unsigned [[vk::ext_capability(spv::CapabilityInt64Atomics)]] [[vk::ext_instruction(spv::OpAtomicIAdd)]] enable_if_t<is_same_v<T,uint64_t> || is_same_v<T,int64_t>, T> atomicIAdd([[vk::ext_reference]] T ptr, uint32_t memoryScope, uint32_t memorySemantics, T value); template<typename T, typename Ptr_T> // DXC Workaround [[vk::ext_capability(spv::CapabilityInt64Atomics)]] [[vk::ext_instruction(spv::OpAtomicIAdd)]] 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); template<typename T> // integers operate on 2s complement so same op for signed and unsigned [[vk::ext_instruction(spv::OpAtomicISub)]] 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); template<typename T, typename Ptr_T> // DXC Workaround [[vk::ext_instruction(spv::OpAtomicISub)]] 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); template<typename T> // integers operate on 2s complement so same op for signed and unsigned [[vk::ext_capability(spv::CapabilityInt64Atomics)]] [[vk::ext_instruction(spv::OpAtomicISub)]] enable_if_t<is_same_v<T,uint64_t> || is_same_v<T,int64_t>, T> atomicISub([[vk::ext_reference]] T ptr, uint32_t memoryScope, uint32_t memorySemantics, T value); template<typename T, typename Ptr_T> // DXC Workaround [[vk::ext_capability(spv::CapabilityInt64Atomics)]] [[vk::ext_instruction(spv::OpAtomicISub)]] 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); template<typename T> [[vk::ext_instruction(spv::OpAtomicAnd)]] 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); template<typename T, typename Ptr_T> // DXC Workaround [[vk::ext_instruction(spv::OpAtomicAnd)]] 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); template<typename T> [[vk::ext_instruction(spv::OpAtomicOr)]] 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); template<typename T, typename Ptr_T> // DXC Workaround [[vk::ext_instruction(spv::OpAtomicOr)]] 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); template<typename T> [[vk::ext_instruction(spv::OpAtomicXor)]] 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); template<typename T, typename Ptr_T> // DXC Workaround [[vk::ext_instruction(spv::OpAtomicXor)]] 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); template<typename Signed> [[vk::ext_instruction( spv::OpAtomicSMin )]] 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); template<typename Signed, typename Ptr_T> // DXC Workaround [[vk::ext_instruction(spv::OpAtomicSMin)]] 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); template<typename Unsigned> [[vk::ext_instruction( spv::OpAtomicUMin )]] enable_if_t<is_same_v<Unsigned,uint32_t>, Unsigned> atomicUMin([[vk::ext_reference]] Unsigned ptr, uint32_t memoryScope, uint32_t memorySemantics, Unsigned value); template<typename Unsigned, typename Ptr_T> // DXC Workaround [[vk::ext_instruction(spv::OpAtomicUMin)]] 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); template<typename Signed> [[vk::ext_instruction( spv::OpAtomicSMax )]] enable_if_t<is_same_v<Signed,int32_t>, Signed> atomicSMax([[vk::ext_reference]] Signed ptr, uint32_t memoryScope, uint32_t memorySemantics, Signed value); template<typename Signed, typename Ptr_T> // DXC Workaround [[vk::ext_instruction(spv::OpAtomicSMax)]] 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); template<typename Unsigned> [[vk::ext_instruction( spv::OpAtomicUMax )]] 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); template<typename Unsigned, typename Ptr_T> // DXC Workaround [[vk::ext_instruction(spv::OpAtomicUMax)]] 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); template<typename T> [[vk::ext_instruction(spv::OpAtomicExchange)]] T atomicExchange([[vk::ext_reference]] T ptr, uint32_t memoryScope, uint32_t memorySemantics, T value); template<typename T, typename Ptr_T> // DXC Workaround [[vk::ext_instruction(spv::OpAtomicExchange)]] enable_if_t<is_pointer_v<Ptr_T>, T> atomicExchange(Ptr_T ptr, uint32_t memoryScope, uint32_t memorySemantics, T value); template<typename T> [[vk::ext_instruction(spv::OpAtomicCompareExchange)]] T atomicCompareExchange([[vk::ext_reference]] T ptr, uint32_t memoryScope, uint32_t memSemanticsEqual, uint32_t memSemanticsUnequal, T value, T comparator); template<typename T, typename Ptr_T> // DXC Workaround [[vk::ext_instruction(spv::OpAtomicCompareExchange)]] 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); template<typename T, uint32_t alignment> [[vk::ext_capability(spv::CapabilityPhysicalStorageBufferAddresses)]] [[vk::ext_instruction(spv::OpLoad)]] T load(bda_pointer_t<T> pointer, [[vk::ext_literal]] uint32_t __aligned = /*Aligned*/0x00000002, [[vk::ext_literal]] uint32_t __alignment = alignment); template<typename T, typename P> [[vk::ext_instruction(spv::OpLoad)]] enable_if_t<is_pointer_v<P>,T> load(P pointer); template<typename T, uint32_t alignment> [[vk::ext_capability(spv::CapabilityPhysicalStorageBufferAddresses)]] [[vk::ext_instruction(spv::OpStore)]] void store(bda_pointer_t<T> pointer, T obj, [[vk::ext_literal]] uint32_t __aligned = /*Aligned*/0x00000002, [[vk::ext_literal]] uint32_t __alignment = alignment); template<typename T, typename P> [[vk::ext_instruction(spv::OpStore)]] enable_if_t<is_pointer_v<P>,void> store(P pointer, T obj); // Memory Semantics link here: https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#Memory_Semantics_-id- // https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#_memory_semantics_id // By providing memory semantics None we do both control and memory barrier as is done in GLSL [[vk::ext_instruction( spv::OpControlBarrier )]] void controlBarrier(uint32_t executionScope, uint32_t memoryScope, uint32_t memorySemantics); [[vk::ext_instruction( spv::OpMemoryBarrier )]] void memoryBarrier(uint32_t memoryScope, uint32_t memorySemantics); // 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) // TODO: better constraints, one should only be able to cast fundamental types, etc. https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#OpBitcast #line 292 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/spirv_intrinsics/core.hlsl" template<class T, class U> [[vk::ext_instruction(spv::OpBitcast)]] T bitcast(U); template<typename Integral> [[vk::ext_instruction( spv::OpBitFieldUExtract )]] enable_if_t<is_integral_v<Integral>, Integral> bitFieldUExtract( Integral val, uint32_t offsetBits, uint32_t numBits ); template<typename Integral> [[vk::ext_instruction( spv::OpBitFieldSExtract )]] enable_if_t<is_integral_v<Integral>, Integral> bitFieldSExtract( Integral val, uint32_t offsetBits, uint32_t numBits ); template<typename Integral> [[vk::ext_instruction( spv::OpBitFieldInsert )]] enable_if_t<is_integral_v<Integral>, Integral> bitFieldInsert( Integral base, Integral insert, uint32_t offset, uint32_t count ); template<typename Integral> [[vk::ext_instruction( spv::OpBitReverse )]] enable_if_t<is_integral_v<Integral>, Integral> bitReverse( Integral base ); template<typename T ,::nbl::hlsl::enable_if_t<(is_floating_point_v<T> && is_scalar_v<T>),bool> = true> [[vk::ext_instruction( spv::OpIsNan )]] bool isNan(T val); template<typename T ,::nbl::hlsl::enable_if_t<(is_floating_point_v<T> && is_scalar_v<T>),bool> = true> [[vk::ext_instruction( spv::OpIsInf )]] bool isInf(T val); template<typename T ,::nbl::hlsl::enable_if_t<(is_floating_point_v<T> && is_vector_v<T>),bool> = true> [[vk::ext_instruction(spv::OpIsNan)]] vector<bool, vector_traits<T>::Dimension> isNan(T val); template<typename T ,::nbl::hlsl::enable_if_t<(is_floating_point_v<T> && is_vector_v<T>),bool> = true> [[vk::ext_instruction(spv::OpIsInf)]] vector<bool, vector_traits<T>::Dimension> isInf(T val); template<typename Vector ,::nbl::hlsl::enable_if_t<(is_vector_v<Vector>),bool> = true> [[vk::ext_instruction( spv::OpDot )]] typename vector_traits<Vector>::scalar_type dot(Vector lhs, Vector rhs); template<typename Matrix> [[vk::ext_instruction( spv::OpTranspose )]] Matrix transpose(Matrix mat); template<typename Integral> [[vk::ext_instruction(spv::OpBitCount)]] enable_if_t<is_integral_v<Integral>, Integral> bitCount(Integral mat); template<typename BooleanVector> [[vk::ext_instruction(spv::OpAll)]] enable_if_t<is_vector_v<BooleanVector> && is_same_v<typename vector_traits<BooleanVector>::scalar_type, bool>, BooleanVector> all(BooleanVector vec); template<typename BooleanVector> [[vk::ext_instruction(spv::OpAny)]] enable_if_t<is_vector_v<BooleanVector>&& is_same_v<typename vector_traits<BooleanVector>::scalar_type, bool>, BooleanVector> any(BooleanVector vec); // If Condition is a vector, ResultType must be a vector with the same number of components. Using (p -> q) = (~p v q) template<typename Condition, typename ResultType ,::nbl::hlsl::enable_if_t<(concepts::Boolean<Condition> && (! concepts::Vector<Condition> || (concepts::Vector<ResultType> && (extent_v<Condition> == extent_v<ResultType>)))),bool> = true> [[vk::ext_instruction(spv::OpSelect)]] ResultType select(Condition condition, ResultType object1, ResultType object2); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::UnsignedIntegral<T>),bool> = true> [[vk::ext_instruction(spv::OpIAddCarry)]] AddCarryOutput<T> addCarry(T operand1, T operand2); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::UnsignedIntegral<T>),bool> = true> [[vk::ext_instruction(spv::OpISubBorrow)]] SubBorrowOutput<T> subBorrow(T operand1, T operand2); template<typename T ,::nbl::hlsl::enable_if_t<(is_integral_v<T> && !is_matrix_v<T>),bool> = true> [[vk::ext_instruction(spv::OpIEqual)]] conditional_t<is_vector_v<T>, vector<bool, vector_traits<T>::Dimension>, bool> IEqual(T lhs, T rhs); template<typename T ,::nbl::hlsl::enable_if_t<(is_floating_point_v<T> && !is_matrix_v<T>),bool> = true> [[vk::ext_instruction(spv::OpFOrdEqual)]] conditional_t<is_vector_v<T>, vector<bool, vector_traits<T>::Dimension>, bool> FOrdEqual(T lhs, T rhs); template<typename T, typename U ,::nbl::hlsl::enable_if_t<(!is_matrix_v<T> && !is_matrix_v<U> && is_same_v<typename vector_traits<U>::scalar_type, bool>),bool> = true> [[vk::ext_instruction(spv::OpSelect)]] T select(U a, T x, T y); } } } #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts.hlsl" // Copyright (C) 2023-2024 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/tgmath/output_structs.hlsl" // Copyright (C) 2023 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts/core.hlsl" // Copyright (C) 2024-2025 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts/vector.hlsl" // Copyright (C) 2024-2025 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 11 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/tgmath/output_structs.hlsl" namespace nbl { namespace hlsl { template<typename T ,typename __requires=void> struct ModfOutput; template<typename T> struct ModfOutput<T ,::nbl::hlsl::enable_if_t<(concepts::FloatingPoint<T>),void> > { T fractionalPart; T wholeNumberPart; }; template<typename T ,typename __requires=void> struct FrexpOutput; template<typename T> struct FrexpOutput<T ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointScalar<T>),void> > { T significand; int exponent; }; template<typename T> struct FrexpOutput<T ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointVector<T>),void> > { T significand; vector<int, vector_traits<T>::Dimension> exponent; }; } } #line 1 "C:/Users/Rynair/Desktop/Nabla/3rdparty/dxc/dxc/external/SPIRV-Headers/include/spirv/unified1/GLSL.std.450.h" /* ** SPDX-FileCopyrightText: 2014-2024 The Khronos Group Inc. ** SPDX-License-Identifier: MIT ** ** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS ** KHRONOS STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS ** SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT ** https://www.khronos.org/registry/ */ #line 14 "C:/Users/Rynair/Desktop/Nabla/3rdparty/dxc/dxc/external/SPIRV-Headers/include/spirv/unified1/GLSL.std.450.h" static const int GLSLstd450Version = 100; static const int GLSLstd450Revision = 3; enum GLSLstd450 { GLSLstd450Bad = 0, // Don't use GLSLstd450Round = 1, GLSLstd450RoundEven = 2, GLSLstd450Trunc = 3, GLSLstd450FAbs = 4, GLSLstd450SAbs = 5, GLSLstd450FSign = 6, GLSLstd450SSign = 7, GLSLstd450Floor = 8, GLSLstd450Ceil = 9, GLSLstd450Fract = 10, GLSLstd450Radians = 11, GLSLstd450Degrees = 12, GLSLstd450Sin = 13, GLSLstd450Cos = 14, GLSLstd450Tan = 15, GLSLstd450Asin = 16, GLSLstd450Acos = 17, GLSLstd450Atan = 18, GLSLstd450Sinh = 19, GLSLstd450Cosh = 20, GLSLstd450Tanh = 21, GLSLstd450Asinh = 22, GLSLstd450Acosh = 23, GLSLstd450Atanh = 24, GLSLstd450Atan2 = 25, GLSLstd450Pow = 26, GLSLstd450Exp = 27, GLSLstd450Log = 28, GLSLstd450Exp2 = 29, GLSLstd450Log2 = 30, GLSLstd450Sqrt = 31, GLSLstd450InverseSqrt = 32, GLSLstd450Determinant = 33, GLSLstd450MatrixInverse = 34, GLSLstd450Modf = 35, // second operand needs an OpVariable to write to GLSLstd450ModfStruct = 36, // no OpVariable operand GLSLstd450FMin = 37, GLSLstd450UMin = 38, GLSLstd450SMin = 39, GLSLstd450FMax = 40, GLSLstd450UMax = 41, GLSLstd450SMax = 42, GLSLstd450FClamp = 43, GLSLstd450UClamp = 44, GLSLstd450SClamp = 45, GLSLstd450FMix = 46, GLSLstd450IMix = 47, // Reserved GLSLstd450Step = 48, GLSLstd450SmoothStep = 49, GLSLstd450Fma = 50, GLSLstd450Frexp = 51, // second operand needs an OpVariable to write to GLSLstd450FrexpStruct = 52, // no OpVariable operand GLSLstd450Ldexp = 53, GLSLstd450PackSnorm4x8 = 54, GLSLstd450PackUnorm4x8 = 55, GLSLstd450PackSnorm2x16 = 56, GLSLstd450PackUnorm2x16 = 57, GLSLstd450PackHalf2x16 = 58, GLSLstd450PackDouble2x32 = 59, GLSLstd450UnpackSnorm2x16 = 60, GLSLstd450UnpackUnorm2x16 = 61, GLSLstd450UnpackHalf2x16 = 62, GLSLstd450UnpackSnorm4x8 = 63, GLSLstd450UnpackUnorm4x8 = 64, GLSLstd450UnpackDouble2x32 = 65, GLSLstd450Length = 66, GLSLstd450Distance = 67, GLSLstd450Cross = 68, GLSLstd450Normalize = 69, GLSLstd450FaceForward = 70, GLSLstd450Reflect = 71, GLSLstd450Refract = 72, GLSLstd450FindILsb = 73, GLSLstd450FindSMsb = 74, GLSLstd450FindUMsb = 75, GLSLstd450InterpolateAtCentroid = 76, GLSLstd450InterpolateAtSample = 77, GLSLstd450InterpolateAtOffset = 78, GLSLstd450NMin = 79, GLSLstd450NMax = 80, GLSLstd450NClamp = 81, GLSLstd450Count }; #line 12 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/spirv_intrinsics/glsl.std.450.hlsl" namespace nbl { namespace hlsl { namespace spirv { namespace concepts { // scalar or vector whose component type is floating-point. template<typename T> const static bool FloatingPointVectorOrScalar = is_floating_point_v<T> && (!is_matrix_v<T>); // scalar or vector whose component type is 16-bit or 32-bit floating-point. template<typename T> const static bool FloatingPointVectorOrScalar32or16BitSize = FloatingPointVectorOrScalar<T> && (sizeof(typename vector_traits<T>::scalar_type) == 4 || sizeof(typename vector_traits<T>::scalar_type) == 2); //is interpreted as signed //integer scalar or integer vector types template<typename T> const static bool IntegralVectorOrScalar = is_integral_v<T> && is_signed_v<T> && !is_matrix_v<T>; //interpreted as unsigned //integer scalar or integer vector types template<typename T> const static bool UnsignedIntegralVectorOrScalar = is_integral_v<T> && is_unsigned_v<T> && !is_matrix_v<T>; //be signed integer scalar or signed integer vector types //This instruction is currently limited to 32 - bit width components. template<typename T> const static bool IntegralVectorOrScalar32BitSize = IntegralVectorOrScalar<T> && (sizeof(typename vector_traits<T>::scalar_type) == 4); //be unsigned integer scalar or unsigned integer vector types //This instruction is currently limited to 32 - bit width components. template<typename T> const static bool UnsignedIntegralVectorOrScalar32BitSize = UnsignedIntegralVectorOrScalar<T> && (sizeof(typename vector_traits<T>::scalar_type) == 4); } // Find MSB and LSB restricted to 32-bit width component types https://registry.khronos.org/SPIR-V/specs/unified1/GLSL.std.450.html template<typename T ,::nbl::hlsl::enable_if_t<(concepts::IntegralVectorOrScalar32BitSize<T> || concepts::UnsignedIntegralVectorOrScalar32BitSize<T>),bool> = true> [[vk::ext_instruction(GLSLstd450::GLSLstd450FindILsb, "GLSL.std.450")]] conditional_t<is_vector_v<T>, vector<int32_t, vector_traits<T>::Dimension>, int32_t> findILsb(T value); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::IntegralVectorOrScalar32BitSize<T>),bool> = true> [[vk::ext_instruction(GLSLstd450::GLSLstd450FindSMsb, "GLSL.std.450")]] conditional_t<is_vector_v<T>, vector<int32_t, vector_traits<T>::Dimension>, int32_t> findSMsb(T value); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::UnsignedIntegralVectorOrScalar32BitSize<T>),bool> = true> [[vk::ext_instruction(GLSLstd450::GLSLstd450FindUMsb, "GLSL.std.450")]] conditional_t<is_vector_v<T>, vector<int32_t, vector_traits<T>::Dimension>, int32_t> findUMsb(T value); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointVectorOrScalar32or16BitSize<T>),bool> = true> [[vk::ext_instruction(GLSLstd450::GLSLstd450Pow, "GLSL.std.450")]] T pow(T lhs, T rhs); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointVectorOrScalar32or16BitSize<T>),bool> = true> [[vk::ext_instruction(GLSLstd450::GLSLstd450Exp, "GLSL.std.450")]] T exp(T val); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointVectorOrScalar32or16BitSize<T>),bool> = true> [[vk::ext_instruction(GLSLstd450::GLSLstd450Exp2, "GLSL.std.450")]] T exp2(T val); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointVectorOrScalar32or16BitSize<T>),bool> = true> [[vk::ext_instruction(GLSLstd450::GLSLstd450Log, "GLSL.std.450")]] T log(T val); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointVectorOrScalar32or16BitSize<T>),bool> = true> [[vk::ext_instruction(GLSLstd450::GLSLstd450Log2, "GLSL.std.450")]] T log2(T val); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointVectorOrScalar<T>),bool> = true> [[vk::ext_instruction(GLSLstd450::GLSLstd450Sqrt, "GLSL.std.450")]] T sqrt(T val); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointVectorOrScalar<T>),bool> = true> [[vk::ext_instruction(GLSLstd450::GLSLstd450InverseSqrt, "GLSL.std.450")]] T inverseSqrt(T val); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointVectorOrScalar<T>),bool> = true> [[vk::ext_instruction(GLSLstd450::GLSLstd450Floor, "GLSL.std.450")]] T floor(T val); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointVectorOrScalar<T> && is_vector_v<T> && (vector_traits<T>::Dimension == 3)),bool> = true> [[vk::ext_instruction(GLSLstd450::GLSLstd450Cross, "GLSL.std.450")]] T cross(const in T lhs, const in T rhs); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointVectorOrScalar<T>),bool> = true> [[vk::ext_instruction(GLSLstd450::GLSLstd450FMix, "GLSL.std.450")]] T fMix(T x, T y, T a); template<typename SquareMatrix ,::nbl::hlsl::enable_if_t<(matrix_traits<SquareMatrix>::Square),bool> = true> [[vk::ext_instruction(GLSLstd450::GLSLstd450Determinant, "GLSL.std.450")]] typename matrix_traits<SquareMatrix>::scalar_type determinant(const in SquareMatrix mat); template<typename SquareMatrix ,::nbl::hlsl::enable_if_t<(matrix_traits<SquareMatrix>::Square),bool> = true> [[vk::ext_instruction(GLSLstd450MatrixInverse, "GLSL.std.450")]] SquareMatrix matrixInverse(const in SquareMatrix mat); [[vk::ext_instruction(GLSLstd450UnpackSnorm2x16, "GLSL.std.450")]] float32_t2 unpackSnorm2x16(uint32_t p); [[vk::ext_instruction(GLSLstd450UnpackSnorm4x8, "GLSL.std.450")]] float32_t4 unpackSnorm4x8(uint32_t p); [[vk::ext_instruction(GLSLstd450UnpackUnorm4x8, "GLSL.std.450")]] float32_t4 unpackUnorm4x8(uint32_t p); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointVectorOrScalar<T>),bool> = true> [[vk::ext_instruction(GLSLstd450Length, "GLSL.std.450")]] typename vector_traits<T>::scalar_type length(T vec); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointVectorOrScalar<T>),bool> = true> [[vk::ext_instruction(GLSLstd450Normalize, "GLSL.std.450")]] T normalize(T vec); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointVectorOrScalar<T>),bool> = true> [[vk::ext_instruction(GLSLstd450FClamp, "GLSL.std.450")]] T fClamp(T val, T _min, T _max); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::UnsignedIntegralVectorOrScalar<T>),bool> = true> [[vk::ext_instruction(GLSLstd450UClamp, "GLSL.std.450")]] T uClamp(T val, T _min, T _max); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::IntegralVectorOrScalar<T>),bool> = true> [[vk::ext_instruction(GLSLstd450SClamp, "GLSL.std.450")]] T sClamp(T val, T _min, T _max); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointVectorOrScalar<T>),bool> = true> [[vk::ext_instruction(GLSLstd450FMin, "GLSL.std.450")]] T fMin(T a, T b); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::UnsignedIntegralVectorOrScalar<T>),bool> = true> [[vk::ext_instruction(GLSLstd450UMin, "GLSL.std.450")]] T uMin(T a, T b); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::IntegralVectorOrScalar<T>),bool> = true> [[vk::ext_instruction(GLSLstd450SMin, "GLSL.std.450")]] T sMin(T a, T b); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointVectorOrScalar<T>),bool> = true> [[vk::ext_instruction(GLSLstd450FMax, "GLSL.std.450")]] T fMax(T a, T b); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::UnsignedIntegralVectorOrScalar<T>),bool> = true> [[vk::ext_instruction(GLSLstd450UMax, "GLSL.std.450")]] T uMax(T a, T b); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::IntegralVectorOrScalar<T>),bool> = true> [[vk::ext_instruction(GLSLstd450SMax, "GLSL.std.450")]] T sMax(T a, T b); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointVectorOrScalar<T>),bool> = true> [[vk::ext_instruction(GLSLstd450FAbs, "GLSL.std.450")]] T fAbs(T val); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::IntegralVectorOrScalar<T>),bool> = true> [[vk::ext_instruction(GLSLstd450SAbs, "GLSL.std.450")]] T sAbs(T val); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointVectorOrScalar32or16BitSize<T>),bool> = true> [[vk::ext_instruction(GLSLstd450Sin, "GLSL.std.450")]] T sin(T val); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointVectorOrScalar32or16BitSize<T>),bool> = true> [[vk::ext_instruction(GLSLstd450Cos, "GLSL.std.450")]] T cos(T val); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointVectorOrScalar32or16BitSize<T>),bool> = true> [[vk::ext_instruction(GLSLstd450Acos, "GLSL.std.450")]] T acos(T val); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointVectorOrScalar32or16BitSize<T>),bool> = true> [[vk::ext_instruction(GLSLstd450Tan, "GLSL.std.450")]] T tan(T val); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointVectorOrScalar32or16BitSize<T>),bool> = true> [[vk::ext_instruction(GLSLstd450Asin, "GLSL.std.450")]] T asin(T val); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointVectorOrScalar32or16BitSize<T>),bool> = true> [[vk::ext_instruction(GLSLstd450Atan, "GLSL.std.450")]] T atan(T val); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointVectorOrScalar32or16BitSize<T>),bool> = true> [[vk::ext_instruction(GLSLstd450Sinh, "GLSL.std.450")]] T sinh(T val); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointVectorOrScalar32or16BitSize<T>),bool> = true> [[vk::ext_instruction(GLSLstd450Cosh, "GLSL.std.450")]] T cosh(T val); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointVectorOrScalar32or16BitSize<T>),bool> = true> [[vk::ext_instruction(GLSLstd450Tanh, "GLSL.std.450")]] T tanh(T val); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointVectorOrScalar32or16BitSize<T>),bool> = true> [[vk::ext_instruction(GLSLstd450Asinh, "GLSL.std.450")]] T asinh(T val); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointVectorOrScalar32or16BitSize<T>),bool> = true> [[vk::ext_instruction(GLSLstd450Acosh, "GLSL.std.450")]] T acosh(T val); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointVectorOrScalar32or16BitSize<T>),bool> = true> [[vk::ext_instruction(GLSLstd450Atanh, "GLSL.std.450")]] T atanh(T val); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointVectorOrScalar32or16BitSize<T>),bool> = true> [[vk::ext_instruction(GLSLstd450Atan2, "GLSL.std.450")]] T atan2(T y, T x); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointVectorOrScalar<T>),bool> = true> [[vk::ext_instruction(GLSLstd450Fract, "GLSL.std.450")]] T fract(T val); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointVectorOrScalar<T>),bool> = true> [[vk::ext_instruction(GLSLstd450Round, "GLSL.std.450")]] T round(T val); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointVectorOrScalar<T>),bool> = true> [[vk::ext_instruction(GLSLstd450RoundEven, "GLSL.std.450")]] T roundEven(T val); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointVectorOrScalar<T>),bool> = true> [[vk::ext_instruction(GLSLstd450Trunc, "GLSL.std.450")]] T trunc(T val); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointVectorOrScalar<T>),bool> = true> [[vk::ext_instruction(GLSLstd450Ceil, "GLSL.std.450")]] T ceil(T val); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointVectorOrScalar<T>),bool> = true> [[vk::ext_instruction(GLSLstd450Fma, "GLSL.std.450")]] T fma(T x, T y, T z); template<typename T, typename U ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointVectorOrScalar<T> && (concepts::IntegralVectorOrScalar<U> || concepts::UnsignedIntegralVectorOrScalar<U>) && (vector_traits<T>::Dimension == vector_traits<U>::Dimension)),bool> = true> #line 239 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/spirv_intrinsics/glsl.std.450.hlsl" [[vk::ext_instruction(GLSLstd450Ldexp, "GLSL.std.450")]] T ldexp(T arg, U exp); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointVectorOrScalar<T>),bool> = true> [[vk::ext_instruction(GLSLstd450FSign, "GLSL.std.450")]] T fSign(T val); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::IntegralVectorOrScalar<T>),bool> = true> [[vk::ext_instruction(GLSLstd450SSign, "GLSL.std.450")]] T sSign(T val); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointVectorOrScalar32or16BitSize<T>),bool> = true> [[vk::ext_instruction(GLSLstd450Radians, "GLSL.std.450")]] T radians(T degrees); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointVectorOrScalar32or16BitSize<T>),bool> = true> [[vk::ext_instruction(GLSLstd450Degrees, "GLSL.std.450")]] T degrees(T radians); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointVectorOrScalar<T>),bool> = true> [[vk::ext_instruction(GLSLstd450Step, "GLSL.std.450")]] T step(T edge, T x); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointVectorOrScalar<T>),bool> = true> [[vk::ext_instruction(GLSLstd450SmoothStep, "GLSL.std.450")]] T smoothStep(T edge0, T edge1, T x); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointVectorOrScalar<T>),bool> = true> [[vk::ext_instruction(GLSLstd450FaceForward, "GLSL.std.450")]] T faceForward(T N, T I, T Nref); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointVectorOrScalar<T>),bool> = true> [[vk::ext_instruction(GLSLstd450Reflect, "GLSL.std.450")]] T reflect(T I, T N); template<typename T, typename U ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointVectorOrScalar<T>),bool> = true> [[vk::ext_instruction(GLSLstd450Refract, "GLSL.std.450")]] T refract(T I, T N, U Nref); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointVectorOrScalar<T>),bool> = true> [[vk::ext_instruction(GLSLstd450ModfStruct, "GLSL.std.450")]] ModfOutput<T> modfStruct(T val); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointVectorOrScalar<T>),bool> = true> [[vk::ext_instruction(GLSLstd450FrexpStruct, "GLSL.std.450")]] FrexpOutput<T> frexpStruct(T val); [[vk::ext_instruction(GLSLstd450PackSnorm4x8, "GLSL.std.450")]] int32_t packSnorm4x8(float32_t4 vec); [[vk::ext_instruction(GLSLstd450PackUnorm4x8, "GLSL.std.450")]] int32_t packUnorm4x8(float32_t4 vec); [[vk::ext_instruction(GLSLstd450PackSnorm2x16, "GLSL.std.450")]] int32_t packSnorm2x16(float32_t2 vec); [[vk::ext_instruction(GLSLstd450PackUnorm2x16, "GLSL.std.450")]] int32_t packUnorm2x16(float32_t2 vec); [[vk::ext_instruction(GLSLstd450PackHalf2x16, "GLSL.std.450")]] int32_t packHalf2x16(float32_t2 vec); [[vk::ext_instruction(GLSLstd450PackDouble2x32, "GLSL.std.450")]] float64_t packDouble2x32(int32_t2 vec); [[vk::ext_instruction(GLSLstd450UnpackSnorm2x16, "GLSL.std.450")]] float32_t2 unpackSnorm2x16(int32_t vec); [[vk::ext_instruction(GLSLstd450UnpackUnorm2x16, "GLSL.std.450")]] float32_t2 unpackUnorm2x16(int32_t vec); [[vk::ext_instruction(GLSLstd450UnpackHalf2x16, "GLSL.std.450")]] float32_t2 unpackHalf2x16(int32_t vec); [[vk::ext_instruction(GLSLstd450UnpackSnorm4x8, "GLSL.std.450")]] float32_t4 unpackSnorm4x8(int32_t vec); [[vk::ext_instruction(GLSLstd450UnpackUnorm4x8, "GLSL.std.450")]] float32_t4 unpackUnorm4x8(int32_t vec); [[vk::ext_instruction(GLSLstd450UnpackDouble2x32, "GLSL.std.450")]] int32_t2 unpackDouble2x32(float64_t vec); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointVectorOrScalar<T>),bool> = true> [[vk::ext_instruction(GLSLstd450NMax, "GLSL.std.450")]] T nMax(T a, T b); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointVectorOrScalar<T>),bool> = true> [[vk::ext_instruction(GLSLstd450NMin, "GLSL.std.450")]] T nMin(T a, T b); template<typename T ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointVectorOrScalar<T>),bool> = true> [[vk::ext_instruction(GLSLstd450NClamp, "GLSL.std.450")]] T nClamp(T val, T _min, T _max); } } } #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/type_traits.hlsl" // Copyright (C) 2022 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/glsl_compat/core.hlsl" // Copyright (C) 2023 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/spirv_intrinsics/core.hlsl" // Copyright (C) 2023 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/type_traits.hlsl" // Copyright (C) 2022 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 12 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/glsl_compat/core.hlsl" namespace nbl { namespace hlsl { namespace glsl { #line 41 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/glsl_compat/core.hlsl" /** * Generic SPIR-V */ // Fun fact: ideally atomics should detect the address space of `ptr` and narrow down the sync-scope properly // https://github.com/microsoft/DirectXShaderCompiler/issues/6508 // Would need own meta-type/tagged-type to implement, without & and fancy operator overloads... not posssible // TODO: we can template on `StorageClass` instead of Ptr_T then resolve the memory scope and semantics properly template<typename T> T atomicAdd([[vk::ext_reference]] inout T ptr, T value) { return spirv::atomicIAdd<T>(ptr, spv::ScopeDevice, spv::MemorySemanticsMaskNone, value); } template<typename T, typename Ptr_T> // DXC Workaround enable_if_t<spirv::is_pointer_v<Ptr_T>, T> atomicAdd(Ptr_T ptr, T value) { return spirv::atomicIAdd<T, Ptr_T>(ptr, spv::ScopeDevice, spv::MemorySemanticsMaskNone, value); } template<typename T> T atomicSub([[vk::ext_reference]] inout T ptr, T value) { return spirv::atomicISub<T>(ptr, spv::ScopeDevice, spv::MemorySemanticsMaskNone, value); } template<typename T, typename Ptr_T> // DXC Workaround enable_if_t<spirv::is_pointer_v<Ptr_T>, T> atomicSub(Ptr_T ptr, T value) { return spirv::atomicISub<T, Ptr_T>(ptr, spv::ScopeDevice, spv::MemorySemanticsMaskNone, value); } template<typename T> T atomicAnd([[vk::ext_reference]] inout T ptr, T value) { return spirv::atomicAnd<T>(ptr, spv::ScopeDevice, spv::MemorySemanticsMaskNone, value); } template<typename T, typename Ptr_T> // DXC Workaround enable_if_t<spirv::is_pointer_v<Ptr_T>, T> atomicAnd(Ptr_T ptr, T value) { return spirv::atomicAnd<T, Ptr_T>(ptr, spv::ScopeDevice, spv::MemorySemanticsMaskNone, value); } template<typename T> T atomicOr([[vk::ext_reference]] inout T ptr, T value) { return spirv::atomicOr<T>(ptr, spv::ScopeDevice, spv::MemorySemanticsMaskNone, value); } template<typename T, typename Ptr_T> // DXC Workaround enable_if_t<spirv::is_pointer_v<Ptr_T>, T> atomicOr(Ptr_T ptr, T value) { return spirv::atomicOr<T, Ptr_T>(ptr, spv::ScopeDevice, spv::MemorySemanticsMaskNone, value); } template<typename T> T atomicXor([[vk::ext_reference]] inout T ptr, T value) { return spirv::atomicXor<T>(ptr, spv::ScopeDevice, spv::MemorySemanticsMaskNone, value); } template<typename T, typename Ptr_T> // DXC Workaround enable_if_t<spirv::is_pointer_v<Ptr_T>, T> atomicXor(Ptr_T ptr, T value) { return spirv::atomicXor<T, Ptr_T>(ptr, spv::ScopeDevice, spv::MemorySemanticsMaskNone, value); } /* TODO: @Hazardu struct dispatchers like for `bitfieldExtract` template<typename T> T atomicMin(NBL_REF_ARG(T) ptr, T value) { } template<typename T> T atomicMax(NBL_REF_ARG(T) ptr, T value) { } */ template<typename T> T atomicExchange([[vk::ext_reference]] inout T ptr, T value) { return spirv::atomicExchange<T>(ptr, spv::ScopeDevice, spv::MemorySemanticsMaskNone, value); } template<typename T, typename Ptr_T> // DXC Workaround enable_if_t<spirv::is_pointer_v<Ptr_T>, T> atomicExchange(Ptr_T ptr, T value) { return spirv::atomicExchange<T, Ptr_T>(ptr, spv::ScopeDevice, spv::MemorySemanticsMaskNone, value); } template<typename T> T atomicCompSwap([[vk::ext_reference]] inout T ptr, T comparator, T value) { return spirv::atomicCompareExchange<T>(ptr, spv::ScopeDevice, spv::MemorySemanticsMaskNone, spv::MemorySemanticsMaskNone, value, comparator); } template<typename T, typename Ptr_T> // DXC Workaround enable_if_t<spirv::is_pointer_v<Ptr_T>, T> atomicCompSwap(Ptr_T ptr, T comparator, T value) { return spirv::atomicCompareExchange<T, Ptr_T>(ptr, spv::ScopeDevice, spv::MemorySemanticsMaskNone, spv::MemorySemanticsMaskNone, value, comparator); } /** * GLSL extended math */ template<typename SquareMatrix> // NBL_REQUIRES() extents are square SquareMatrix inverse(const in SquareMatrix mat) { return spirv::matrixInverse(mat); } float32_t2 unpackSnorm2x16(uint32_t p) { return spirv::unpackSnorm2x16(p); } /** * For Vertex Shaders */ // TODO: Extemely annoying that HLSL doesn't have references, so we can't transparently alias the variables as `&` :( //void gl_Position() {spirv::} uint32_t gl_VertexIndex() {return spirv::VertexIndex;} uint32_t gl_InstanceIndex() {return spirv::InstanceIndex;} /** * For Compute Shaders */ // TODO: Extemely annoying that HLSL doesn't have references, so we can't transparently alias the variables as `const&` :( uint32_t3 gl_NumWorkGroups() {return spirv::NumWorkGroups;} // TODO: DXC BUG prevents us from defining this! uint32_t3 gl_WorkGroupSize(); uint32_t3 gl_WorkGroupID() {return spirv::WorkgroupId;} uint32_t3 gl_LocalInvocationID() {return spirv::LocalInvocationId;} uint32_t3 gl_GlobalInvocationID() {return spirv::GlobalInvocationId;} uint32_t gl_LocalInvocationIndex() {return spirv::LocalInvocationIndex;} void barrier() { spirv::controlBarrier(spv::ScopeWorkgroup, spv::ScopeWorkgroup, spv::MemorySemanticsAcquireReleaseMask | spv::MemorySemanticsWorkgroupMemoryMask); } /** * For Tessellation Control Shaders */ void tess_ctrl_barrier() { spirv::controlBarrier(spv::ScopeWorkgroup, spv::ScopeInvocation, 0); } void memoryBarrierShared() { spirv::memoryBarrier(spv::ScopeDevice, spv::MemorySemanticsAcquireReleaseMask | spv::MemorySemanticsWorkgroupMemoryMask); } namespace impl { template<typename T, bool isSigned, bool isIntegral> struct bitfieldExtract {}; template<typename T, bool isSigned> struct bitfieldExtract<T, isSigned, false> { static T __call( T val, uint32_t offsetBits, uint32_t numBits ) { _Static_assert( is_integral<T>::value, "T is not an integral type!" ); return val; } }; template<typename T> struct bitfieldExtract<T, true, true> { static T __call( T val, uint32_t offsetBits, uint32_t numBits ) { return spirv::bitFieldSExtract<T>( val, offsetBits, numBits ); } }; template<typename T> struct bitfieldExtract<T, false, true> { static T __call( T val, uint32_t offsetBits, uint32_t numBits ) { return spirv::bitFieldUExtract<T>( val, offsetBits, numBits ); } }; } //namespace impl template<typename T> T bitfieldExtract( T val, uint32_t offsetBits, uint32_t numBits ) { return impl::bitfieldExtract<T, is_signed<T>::value, is_integral<T>::value>::__call(val,offsetBits,numBits); } template<typename T> T bitfieldInsert(T base, T insert, uint32_t offset, uint32_t bits) { return spirv::bitFieldInsert<T>(base, insert, offset, bits); } template<typename T> T bitfieldReverse(T value) { return spirv::bitReverse<T>(value); } } } } #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/macros.h" // Copyright (C) 2022 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/spirv_intrinsics/core.hlsl" // Copyright (C) 2023 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 29 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/bit.hlsl" namespace nbl { namespace hlsl { #line 54 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/bit.hlsl" template<class T, class U> enable_if_t<sizeof(T)==sizeof(U),T> bit_cast(U val) { return spirv::bitcast<T,U>(val); } template<typename T, typename S> T rotl(T x, S s); template<typename T, typename S> T rotr(T x, S s); template<typename T, typename S> T rotl(T x, S s) { const T N = 32u; const S r = s % N; if(r >= 0) { return (x << r) | (x >> (N - r)); } else { return (x >> (-r)) | (x << (N - (-r))); } } template<typename T, typename S> T rotr(T x, S s) { const T N = 32u; const S r = s % N; if(r >= 0) { return (x >> r) | (x << (N - r)); } else { return (x << (-r)) | (x >> (N - (-r))); } } namespace impl { template<uint16_t bits> uint16_t clz(uint64_t N) { static const uint64_t SHIFT = bits>>1; static const uint64_t LO_MASK = (1ull<<SHIFT)-1; const bool CHOOSE_HIGH = N & (LO_MASK<<SHIFT); const uint64_t NEXT = (CHOOSE_HIGH ? (N>>SHIFT):N)&LO_MASK; const uint16_t value = uint16_t(clz<SHIFT>(NEXT) + (CHOOSE_HIGH ? 0:SHIFT)); return value; } template<> uint16_t clz<1>(uint64_t N) { return uint16_t(1u-N&1); } } //namespace impl template<typename T> uint16_t countl_zero(T n) { return impl::clz<sizeof(T)*8>(n); } } } #line 8 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/ieee754/impl.hlsl" namespace nbl { namespace hlsl { namespace ieee754 { namespace impl { template <typename T> inline unsigned_integer_of_size_t<sizeof(T)> bitCastToUintType(T x) { using AsUint = unsigned_integer_of_size_t<sizeof(T)>; return bit_cast<AsUint, T>(x); } // to avoid bit cast from uintN_t to uintN_t template <> inline unsigned_integer_of_size_t<2> bitCastToUintType(uint16_t x) { return x; } template <> inline unsigned_integer_of_size_t<4> bitCastToUintType(uint32_t x) { return x; } template <> inline unsigned_integer_of_size_t<8> bitCastToUintType(uint64_t x) { return x; } template <typename T> inline T castBackToFloatType(T x) { using AsFloat = typename float_of_size<sizeof(T)>::type; return bit_cast<AsFloat, T>(x); } template<> inline uint16_t castBackToFloatType(uint16_t x) { return x; } template<> inline uint32_t castBackToFloatType(uint32_t x) { return x; } template<> inline uint64_t castBackToFloatType(uint64_t x) { return x; } } } } } #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts/core.hlsl" // Copyright (C) 2024-2025 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 7 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/ieee754.hlsl" namespace nbl { namespace hlsl { namespace ieee754 { template<typename Float> struct traits_base { _Static_assert(is_same<Float, float16_t>::value || is_same<Float, float32_t>::value || is_same<Float, float64_t>::value); const static int16_t exponentBitCnt = int16_t(0xbeef); const static int16_t mantissaBitCnt = int16_t(0xbeef); }; template<> struct traits_base<float16_t> { const static int16_t exponentBitCnt = 5; const static int16_t mantissaBitCnt = 10; }; template<> struct traits_base<float32_t> { const static int16_t exponentBitCnt = 8; const static int16_t mantissaBitCnt = 23; }; template<> struct traits_base<float64_t> { const static int16_t exponentBitCnt = 11; const static int16_t mantissaBitCnt = 52; }; template<typename Float> struct traits : traits_base<Float> { //static_assert(is_same_v<Float, float16_t> || is_same_v<Float, float32_t> || is_same_v<Float, float64_t>); using bit_rep_t = typename unsigned_integer_of_size<sizeof(Float)>::type; using base_t = traits_base<Float>; const static bit_rep_t signMask = bit_rep_t(0x1ull) << (sizeof(Float) * 8 - 1); const static bit_rep_t exponentMask = ((~bit_rep_t(0)) << base_t::mantissaBitCnt) ^ signMask; const static bit_rep_t mantissaMask = (bit_rep_t(0x1u) << base_t::mantissaBitCnt) - 1; const static int exponentBias = (int(0x1) << (base_t::exponentBitCnt - 1)) - 1; const static bit_rep_t inf = exponentMask; const static bit_rep_t specialValueExp = (1ull << base_t::exponentBitCnt) - 1; const static bit_rep_t quietNaN = exponentMask | (1ull << (base_t::mantissaBitCnt - 1)); const static bit_rep_t max = ((1ull << (sizeof(Float) * 8 - 1)) - 1) & (~(1ull << base_t::mantissaBitCnt)); const static bit_rep_t min = 1ull << base_t::mantissaBitCnt; const static int exponentMax = exponentBias; const static int exponentMin = -(exponentBias - 1); }; template <typename T> inline uint32_t extractBiasedExponent(T x) { using AsUint = typename unsigned_integer_of_size<sizeof(T)>::type; return glsl::bitfieldExtract<AsUint>(ieee754::impl::bitCastToUintType(x), traits<typename float_of_size<sizeof(T)>::type>::mantissaBitCnt, traits<typename float_of_size<sizeof(T)>::type>::exponentBitCnt); } template<> inline uint32_t extractBiasedExponent(uint64_t x) { uint64_t output = (x >> traits<float64_t>::mantissaBitCnt) & (traits<float64_t>::exponentMask >> traits<float64_t>::mantissaBitCnt); return uint32_t(output); } template<> inline uint32_t extractBiasedExponent(float64_t x) { return extractBiasedExponent<uint64_t>(ieee754::impl::bitCastToUintType(x)); } template <typename T> inline int extractExponent(T x) { using AsFloat = typename float_of_size<sizeof(T)>::type; return int(extractBiasedExponent(x)) - traits<AsFloat>::exponentBias; } template <typename T> inline T replaceBiasedExponent(T x, typename unsigned_integer_of_size<sizeof(T)>::type biasedExp) { using AsFloat = typename float_of_size<sizeof(T)>::type; return impl::castBackToFloatType<T>(glsl::bitfieldInsert(ieee754::impl::bitCastToUintType(x), biasedExp, traits<AsFloat>::mantissaBitCnt, traits<AsFloat>::exponentBitCnt)); } // performs no overflow tests, returns x*exp2(n) template <typename T> inline T fastMulExp2(T x, int n) { return replaceBiasedExponent(x, extractBiasedExponent(x) + uint32_t(n)); } template <typename T> inline typename unsigned_integer_of_size<sizeof(T)>::type extractMantissa(T x) { using AsUint = typename unsigned_integer_of_size<sizeof(T)>::type; return ieee754::impl::bitCastToUintType(x) & traits<typename float_of_size<sizeof(T)>::type>::mantissaMask; } template <typename T> inline typename unsigned_integer_of_size<sizeof(T)>::type extractNormalizeMantissa(T x) { using AsUint = typename unsigned_integer_of_size<sizeof(T)>::type; using AsFloat = typename float_of_size<sizeof(T)>::type; return extractMantissa(x) | (AsUint(1) << traits<AsFloat>::mantissaBitCnt); } template <typename T> inline typename unsigned_integer_of_size<sizeof(T)>::type extractSign(T x) { using AsFloat = typename float_of_size<sizeof(T)>::type; return (ieee754::impl::bitCastToUintType(x) & traits<AsFloat>::signMask) >> ((sizeof(T) * 8) - 1); } template <typename T> inline typename unsigned_integer_of_size<sizeof(T)>::type extractSignPreserveBitPattern(T x) { using AsFloat = typename float_of_size<sizeof(T)>::type; return ieee754::impl::bitCastToUintType(x) & traits<AsFloat>::signMask; } template <typename FloatingPoint ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointLikeScalar<FloatingPoint>),bool> = true> inline FloatingPoint copySign(FloatingPoint to, FloatingPoint from) { using AsUint = typename unsigned_integer_of_size<sizeof(FloatingPoint)>::type; const AsUint toAsUint = ieee754::impl::bitCastToUintType(to) & (~ieee754::traits<FloatingPoint>::signMask); const AsUint fromAsUint = ieee754::impl::bitCastToUintType(from); return bit_cast<FloatingPoint>(toAsUint | extractSignPreserveBitPattern(from)); } template <typename FloatingPoint ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointLikeScalar<FloatingPoint>),bool> = true> inline FloatingPoint flipSign(FloatingPoint val, bool flip = true) { using AsFloat = typename float_of_size<sizeof(FloatingPoint)>::type; using AsUint = typename unsigned_integer_of_size<sizeof(FloatingPoint)>::type; const AsUint asUint = ieee754::impl::bitCastToUintType(val); return bit_cast<FloatingPoint>(asUint ^ (flip ? ieee754::traits<AsFloat>::signMask : AsUint(0ull))); } } } } #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts/core.hlsl" // Copyright (C) 2024-2025 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts/vector.hlsl" // Copyright (C) 2024-2025 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts/matrix.hlsl" // Copyright (C) 2024-2025 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts.hlsl" // Copyright (C) 2023-2024 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 11 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts/matrix.hlsl" namespace nbl { namespace hlsl { namespace concepts { template<typename T> const static bool Matrix = is_matrix<T>::value; template<typename T> const static bool Matricial = matrix_traits<T>::IsMatrix; } } } #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/type_traits.hlsl" // Copyright (C) 2022 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 6 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/cpp_compat/promote.hlsl" namespace nbl { namespace hlsl { namespace impl { // partial specialize this for `T=matrix<scalar_t,,>|vector<scalar_t,>` and `U=matrix<scalar_t,,>|vector<scalar_t,>|scalar_t` template<typename T, typename U> struct Promote { inline T operator()(const in U v) { return T(v); } }; template<typename Scalar, typename U> struct Promote<vector <Scalar, 1>, U> { inline enable_if_t<is_scalar<Scalar>::value && is_scalar<U>::value, vector <Scalar, 1> > operator()(const in U v) { vector <Scalar, 1> promoted = {Scalar(v)}; return promoted; } }; template<typename Scalar, typename U> struct Promote<vector <Scalar, 2>, U> { inline enable_if_t<is_scalar<Scalar>::value && is_scalar<U>::value, vector <Scalar, 2> > operator()(const in U v) { vector <Scalar, 2> promoted = {Scalar(v), Scalar(v)}; return promoted; } }; template<typename Scalar, typename U> struct Promote<vector <Scalar, 3>, U> { inline enable_if_t<is_scalar<Scalar>::value && is_scalar<U>::value, vector <Scalar, 3> > operator()(const in U v) { vector <Scalar, 3> promoted = {Scalar(v), Scalar(v), Scalar(v)}; return promoted; } }; template<typename Scalar, typename U> struct Promote<vector <Scalar, 4>, U> { inline enable_if_t<is_scalar<Scalar>::value && is_scalar<U>::value, vector <Scalar, 4> > operator()(const in U v) { vector <Scalar, 4> promoted = {Scalar(v), Scalar(v), Scalar(v), Scalar(v)}; return promoted; } }; } template<typename T, typename U> inline T promote(const U v) // TODO: use NBL_CONST_REF_ARG(U) instead of U v (circular ref) { impl::Promote<T,U> _promote; return _promote(v); } } } #line 6 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/numbers.hlsl" namespace nbl { namespace hlsl { namespace numbers { template <typename float_t> const static float_t e = float_t(2.718281828459045); template <typename float_t> const static float_t log2e = float_t(1.4426950408889634); template <typename float_t> const static float_t log10e = float_t(0.4342944819032518); template <typename float_t> const static float_t pi = float_t(3.141592653589793); template <typename float_t> const static float_t inv_pi = float_t(0.3183098861837907); template <typename float_t> const static float_t inv_sqrtpi = float_t(0.5641895835477563); template <typename float_t> const static float_t ln2 = float_t(0.6931471805599453); template <typename float_t> const static float_t ln10 = float_t(2.302585092994046); template <typename float_t> const static float_t sqrt2 = float_t(1.4142135623730951); template <typename float_t> const static float_t sqrt3 = float_t(1.7320508075688772); template <typename float_t> const static float_t inv_sqrt3 = float_t(0.5773502691896257); template <typename float_t> const static float_t egamma = float_t(0.5772156649015329); template <typename float_t> const static float_t phi = float_t(1.618033988749895); } } } #line 19 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl" namespace nbl { namespace hlsl { namespace cpp_compat_intrinsics_impl { template<typename UnsignedInteger ,::nbl::hlsl::enable_if_t<(hlsl::is_integral_v<UnsignedInteger>&& hlsl::is_unsigned_v<UnsignedInteger>),bool> = true> inline bool isnan_uint_impl(UnsignedInteger val) { using AsFloat = typename float_of_size<sizeof(UnsignedInteger)>::type; const static UnsignedInteger Mask = (UnsignedInteger(0) - 1) >> 1; UnsignedInteger absVal = val & Mask; return absVal > (ieee754::traits<AsFloat>::specialValueExp << ieee754::traits<AsFloat>::mantissaBitCnt); } template<typename UnsignedInteger ,::nbl::hlsl::enable_if_t<(hlsl::is_integral_v<UnsignedInteger>&& hlsl::is_unsigned_v<UnsignedInteger>),bool> = true> inline bool isinf_uint_impl(UnsignedInteger val) { using AsFloat = typename float_of_size<sizeof(UnsignedInteger)>::type; return (val & (~ieee754::traits<AsFloat>::signMask)) == ieee754::traits<AsFloat>::inf; } template<typename T ,typename __requires=void> struct dot_helper; template<typename T ,typename __requires=void> struct cross_helper; template<typename T ,typename __requires=void> struct clamp_helper; template<typename Integer ,typename __requires=void> struct find_msb_helper; template<typename Integer ,typename __requires=void> struct find_lsb_helper; template<typename T ,typename __requires=void> struct bitReverse_helper; template<typename Matrix ,typename __requires=void> struct transpose_helper; template<typename Vector ,typename __requires=void> struct length_helper; template<typename Vector ,typename __requires=void> struct normalize_helper; template<typename T ,typename __requires=void> struct max_helper; template<typename T ,typename __requires=void> struct min_helper; template<typename Integer ,typename __requires=void> struct bitCount_helper; template<typename LhsT, typename RhsT ,typename __requires=void> struct mul_helper; template<typename T ,typename __requires=void> struct determinant_helper; template<typename T ,typename __requires=void> struct inverse_helper; template<typename T ,typename __requires=void> struct rsqrt_helper; template<typename T ,typename __requires=void> struct all_helper; template<typename T ,typename __requires=void> struct any_helper; template<typename B, typename T ,typename __requires=void> struct select_helper; template<typename T ,typename __requires=void> struct bitReverseAs_helper; template<typename T ,typename __requires=void> struct fract_helper; template<typename T, typename U ,typename __requires=void> struct mix_helper; template<typename T ,typename __requires=void> struct sign_helper; template<typename T ,typename __requires=void> struct radians_helper; template<typename T ,typename __requires=void> struct degrees_helper; template<typename T ,typename __requires=void> struct step_helper; template<typename T ,typename __requires=void> struct smoothStep_helper; template<typename T ,typename __requires=void> struct faceForward_helper; template<typename T ,typename __requires=void> struct reflect_helper; template<typename T, typename U ,typename __requires=void> struct refract_helper; template<typename T ,typename __requires=void> struct nMin_helper; template<typename T ,typename __requires=void> struct nMax_helper; template<typename T ,typename __requires=void> struct nClamp_helper; template<typename T ,typename __requires=void> struct addCarry_helper; template<typename T ,typename __requires=void> struct subBorrow_helper; template<typename T ,typename __requires=void> struct undef_helper; template<typename T ,typename __requires=void> struct fma_helper; // it is crucial these partial specializations appear first because thats what makes the helpers match SPIR-V intrinsics first #line 126 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl" // the template<> needs to be written ourselves // return type is __VA_ARGS__ to protect against `,` in templated return types #line 140 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl" template<typename T> struct find_msb_helper<T ,::nbl::hlsl::enable_if_t<(is_same_v<__decltype(spirv:: findUMsb< T >(experimental::declval< T>())), conditional_t<is_vector_v<T>, vector<int32_t, vector_traits<T>::Dimension>, int32_t> >),void> >{ using return_t = conditional_t<is_vector_v<T>, vector<int32_t, vector_traits<T>::Dimension>, int32_t>; static inline return_t __call( const T arg0 ) { return spirv:: findUMsb<T>( arg0 ); }};; template<typename T> struct find_msb_helper<T ,::nbl::hlsl::enable_if_t<(is_same_v<__decltype(spirv:: findSMsb< T >(experimental::declval< T>())), conditional_t<is_vector_v<T>, vector<int32_t, vector_traits<T>::Dimension>, int32_t> >),void> >{ using return_t = conditional_t<is_vector_v<T>, vector<int32_t, vector_traits<T>::Dimension>, int32_t>; static inline return_t __call( const T arg0 ) { return spirv:: findSMsb<T>( arg0 ); }}; template<typename T> struct find_lsb_helper<T ,::nbl::hlsl::enable_if_t<(is_same_v<__decltype(spirv:: findILsb< T >(experimental::declval< T>())), conditional_t<is_vector_v<T>, vector<int32_t, vector_traits<T>::Dimension>, int32_t> >),void> >{ using return_t = conditional_t<is_vector_v<T>, vector<int32_t, vector_traits<T>::Dimension>, int32_t>; static inline return_t __call( const T arg0 ) { return spirv:: findILsb<T>( arg0 ); }}; template<typename T> struct bitReverse_helper<T ,::nbl::hlsl::enable_if_t<(is_same_v<__decltype(spirv:: bitReverse< T >(experimental::declval< T>())), T >),void> >{ using return_t = T; static inline return_t __call( const T arg0 ) { return spirv:: bitReverse<T>( arg0 ); }}; template<typename T> struct dot_helper<T ,::nbl::hlsl::enable_if_t<(is_same_v<__decltype(spirv:: dot< T >(experimental::declval< T>() , experimental::declval< T>())), typename vector_traits<T>::scalar_type >),void> >{ using return_t = typename vector_traits<T>::scalar_type; static inline return_t __call( const T arg0 , const T arg1 ) { return spirv:: dot<T>( arg0 , arg1 ); }}; template<typename T> struct transpose_helper<T ,::nbl::hlsl::enable_if_t<(is_same_v<__decltype(spirv:: transpose< T >(experimental::declval< T>())), T >),void> >{ using return_t = T; static inline return_t __call( const T arg0 ) { return spirv:: transpose<T>( arg0 ); }}; template<typename T> struct length_helper<T ,::nbl::hlsl::enable_if_t<(is_same_v<__decltype(spirv:: length< T >(experimental::declval< T>())), typename vector_traits<T>::scalar_type >),void> >{ using return_t = typename vector_traits<T>::scalar_type; static inline return_t __call( const T arg0 ) { return spirv:: length<T>( arg0 ); }}; template<typename T> struct normalize_helper<T ,::nbl::hlsl::enable_if_t<(is_same_v<__decltype(spirv:: normalize< T >(experimental::declval< T>())), T >),void> >{ using return_t = T; static inline return_t __call( const T arg0 ) { return spirv:: normalize<T>( arg0 ); }}; template<typename T> struct rsqrt_helper<T ,::nbl::hlsl::enable_if_t<(is_same_v<__decltype(spirv:: inverseSqrt< T >(experimental::declval< T>())), T >),void> >{ using return_t = T; static inline return_t __call( const T arg0 ) { return spirv:: inverseSqrt<T>( arg0 ); }}; template<typename T> struct fract_helper<T ,::nbl::hlsl::enable_if_t<(is_same_v<__decltype(spirv:: fract< T >(experimental::declval< T>())), T >),void> >{ using return_t = T; static inline return_t __call( const T arg0 ) { return spirv:: fract<T>( arg0 ); }}; template<typename T> struct all_helper<T ,::nbl::hlsl::enable_if_t<(is_same_v<__decltype(spirv:: all< T >(experimental::declval< T>())), T >),void> >{ using return_t = T; static inline return_t __call( const T arg0 ) { return spirv:: all<T>( arg0 ); }}; template<typename T> struct any_helper<T ,::nbl::hlsl::enable_if_t<(is_same_v<__decltype(spirv:: any< T >(experimental::declval< T>())), T >),void> >{ using return_t = T; static inline return_t __call( const T arg0 ) { return spirv:: any<T>( arg0 ); }}; template<typename B, typename T> struct select_helper<B , T ,::nbl::hlsl::enable_if_t<(is_same_v<__decltype(spirv:: select< B , T >(experimental::declval< B>() , experimental::declval< T>() , experimental::declval< T>())), T >),void> >{ using return_t = T; static inline return_t __call( const B arg0 , const T arg1 , const T arg2 ) { return spirv:: select<B , T>( arg0 , arg1 , arg2 ); }}; template<typename T> struct sign_helper<T ,::nbl::hlsl::enable_if_t<(is_same_v<__decltype(spirv:: fSign< T >(experimental::declval< T>())), T >),void> >{ using return_t = T; static inline return_t __call( const T arg0 ) { return spirv:: fSign<T>( arg0 ); }}; template<typename T> struct sign_helper<T ,::nbl::hlsl::enable_if_t<(is_same_v<__decltype(spirv:: sSign< T >(experimental::declval< T>())), T >),void> >{ using return_t = T; static inline return_t __call( const T arg0 ) { return spirv:: sSign<T>( arg0 ); }}; template<typename T> struct radians_helper<T ,::nbl::hlsl::enable_if_t<(is_same_v<__decltype(spirv:: radians< T >(experimental::declval< T>())), T >),void> >{ using return_t = T; static inline return_t __call( const T arg0 ) { return spirv:: radians<T>( arg0 ); }}; template<typename T> struct degrees_helper<T ,::nbl::hlsl::enable_if_t<(is_same_v<__decltype(spirv:: degrees< T >(experimental::declval< T>())), T >),void> >{ using return_t = T; static inline return_t __call( const T arg0 ) { return spirv:: degrees<T>( arg0 ); }}; template<typename T> struct max_helper<T ,::nbl::hlsl::enable_if_t<(is_same_v<__decltype(spirv:: fMax< T >(experimental::declval< T>() , experimental::declval< T>())), T >),void> >{ using return_t = T; static inline return_t __call( const T arg0 , const T arg1 ) { return spirv:: fMax<T>( arg0 , arg1 ); }}; template<typename T> struct max_helper<T ,::nbl::hlsl::enable_if_t<(is_same_v<__decltype(spirv:: uMax< T >(experimental::declval< T>() , experimental::declval< T>())), T >),void> >{ using return_t = T; static inline return_t __call( const T arg0 , const T arg1 ) { return spirv:: uMax<T>( arg0 , arg1 ); }}; template<typename T> struct max_helper<T ,::nbl::hlsl::enable_if_t<(is_same_v<__decltype(spirv:: sMax< T >(experimental::declval< T>() , experimental::declval< T>())), T >),void> >{ using return_t = T; static inline return_t __call( const T arg0 , const T arg1 ) { return spirv:: sMax<T>( arg0 , arg1 ); }}; template<typename T> struct min_helper<T ,::nbl::hlsl::enable_if_t<(is_same_v<__decltype(spirv:: fMin< T >(experimental::declval< T>() , experimental::declval< T>())), T >),void> >{ using return_t = T; static inline return_t __call( const T arg0 , const T arg1 ) { return spirv:: fMin<T>( arg0 , arg1 ); }}; template<typename T> struct min_helper<T ,::nbl::hlsl::enable_if_t<(is_same_v<__decltype(spirv:: uMin< T >(experimental::declval< T>() , experimental::declval< T>())), T >),void> >{ using return_t = T; static inline return_t __call( const T arg0 , const T arg1 ) { return spirv:: uMin<T>( arg0 , arg1 ); }}; template<typename T> struct min_helper<T ,::nbl::hlsl::enable_if_t<(is_same_v<__decltype(spirv:: sMin< T >(experimental::declval< T>() , experimental::declval< T>())), T >),void> >{ using return_t = T; static inline return_t __call( const T arg0 , const T arg1 ) { return spirv:: sMin<T>( arg0 , arg1 ); }}; template<typename T> struct step_helper<T ,::nbl::hlsl::enable_if_t<(is_same_v<__decltype(spirv:: step< T >(experimental::declval< T>() , experimental::declval< T>())), T >),void> >{ using return_t = T; static inline return_t __call( const T arg0 , const T arg1 ) { return spirv:: step<T>( arg0 , arg1 ); }}; template<typename T> struct reflect_helper<T ,::nbl::hlsl::enable_if_t<(is_same_v<__decltype(spirv:: reflect< T >(experimental::declval< T>() , experimental::declval< T>())), T >),void> >{ using return_t = T; static inline return_t __call( const T arg0 , const T arg1 ) { return spirv:: reflect<T>( arg0 , arg1 ); }}; template<typename T> struct clamp_helper<T ,::nbl::hlsl::enable_if_t<(is_same_v<__decltype(spirv:: fClamp< T >(experimental::declval< T>() , experimental::declval< T>() , experimental::declval< T>())), T >),void> >{ using return_t = T; static inline return_t __call( const T arg0 , const T arg1 , const T arg2 ) { return spirv:: fClamp<T>( arg0 , arg1 , arg2 ); }}; template<typename T> struct clamp_helper<T ,::nbl::hlsl::enable_if_t<(is_same_v<__decltype(spirv:: uClamp< T >(experimental::declval< T>() , experimental::declval< T>() , experimental::declval< T>())), T >),void> >{ using return_t = T; static inline return_t __call( const T arg0 , const T arg1 , const T arg2 ) { return spirv:: uClamp<T>( arg0 , arg1 , arg2 ); }}; template<typename T> struct clamp_helper<T ,::nbl::hlsl::enable_if_t<(is_same_v<__decltype(spirv:: sClamp< T >(experimental::declval< T>() , experimental::declval< T>() , experimental::declval< T>())), T >),void> >{ using return_t = T; static inline return_t __call( const T arg0 , const T arg1 , const T arg2 ) { return spirv:: sClamp<T>( arg0 , arg1 , arg2 ); }}; template<typename T> struct smoothStep_helper<T ,::nbl::hlsl::enable_if_t<(is_same_v<__decltype(spirv:: smoothStep< T >(experimental::declval< T>() , experimental::declval< T>() , experimental::declval< T>())), T >),void> >{ using return_t = T; static inline return_t __call( const T arg0 , const T arg1 , const T arg2 ) { return spirv:: smoothStep<T>( arg0 , arg1 , arg2 ); }}; template<typename T> struct faceForward_helper<T ,::nbl::hlsl::enable_if_t<(is_same_v<__decltype(spirv:: faceForward< T >(experimental::declval< T>() , experimental::declval< T>() , experimental::declval< T>())), T >),void> >{ using return_t = T; static inline return_t __call( const T arg0 , const T arg1 , const T arg2 ) { return spirv:: faceForward<T>( arg0 , arg1 , arg2 ); }}; template<typename T, typename U> struct refract_helper<T , U ,::nbl::hlsl::enable_if_t<(is_same_v<__decltype(spirv:: refract< T , U >(experimental::declval< T>() , experimental::declval< T>() , experimental::declval< U>())), T >),void> >{ using return_t = T; static inline return_t __call( const T arg0 , const T arg1 , const U arg2 ) { return spirv:: refract<T , U>( arg0 , arg1 , arg2 ); }}; template<typename T> struct nMax_helper<T ,::nbl::hlsl::enable_if_t<(is_same_v<__decltype(spirv:: nMax< T >(experimental::declval< T>() , experimental::declval< T>())), T >),void> >{ using return_t = T; static inline return_t __call( const T arg0 , const T arg1 ) { return spirv:: nMax<T>( arg0 , arg1 ); }}; template<typename T> struct nMin_helper<T ,::nbl::hlsl::enable_if_t<(is_same_v<__decltype(spirv:: nMin< T >(experimental::declval< T>() , experimental::declval< T>())), T >),void> >{ using return_t = T; static inline return_t __call( const T arg0 , const T arg1 ) { return spirv:: nMin<T>( arg0 , arg1 ); }}; template<typename T> struct nClamp_helper<T ,::nbl::hlsl::enable_if_t<(is_same_v<__decltype(spirv:: nClamp< T >(experimental::declval< T>() , experimental::declval< T>())), T >),void> >{ using return_t = T; static inline return_t __call( const T arg0 , const T arg1 ) { return spirv:: nClamp<T>( arg0 , arg1 ); }}; // Can use trivial case and not worry about restricting `T` with a concept since `spirv::AddCarryOutput / SubBorrowOutput` already take care of that template<typename T> struct addCarry_helper<T ,::nbl::hlsl::enable_if_t<(is_same_v<__decltype(spirv:: addCarry< T >(experimental::declval< T>() , experimental::declval< T>())), spirv::AddCarryOutput<T> >),void> >{ using return_t = spirv::AddCarryOutput<T>; static inline return_t __call( const T arg0 , const T arg1 ) { return spirv:: addCarry<T>( arg0 , arg1 ); }}; template<typename T> struct subBorrow_helper<T ,::nbl::hlsl::enable_if_t<(is_same_v<__decltype(spirv:: subBorrow< T >(experimental::declval< T>() , experimental::declval< T>())), spirv::SubBorrowOutput<T> >),void> >{ using return_t = spirv::SubBorrowOutput<T>; static inline return_t __call( const T arg0 , const T arg1 ) { return spirv:: subBorrow<T>( arg0 , arg1 ); }}; template<typename T> struct undef_helper<T ,::nbl::hlsl::enable_if_t<(is_same_v<__decltype(spirv:: undef< T >()), T >),void> >{ using return_t = T; static inline return_t __call( ) { return spirv:: undef<T>( ); }}; template<typename T> struct fma_helper<T ,::nbl::hlsl::enable_if_t<(is_same_v<__decltype(spirv:: fma< T >(experimental::declval< T>() , experimental::declval< T>() , experimental::declval< T>())), T >),void> >{ using return_t = T; static inline return_t __call( const T arg0 , const T arg1 , const T arg2 ) { return spirv:: fma<T>( arg0 , arg1 , arg2 ); }}; #line 183 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl" template<typename T> struct bitCount_helper<T ,::nbl::hlsl::enable_if_t<(is_same_v<__decltype(spirv:: bitCount< T >(experimental::declval< T>())), conditional_t<is_vector_v<T>, vector<int32_t, vector_traits<T>::Dimension>, int32_t> >),void> >{ using return_t = conditional_t<is_vector_v<T>, vector<int32_t, vector_traits<T>::Dimension>, int32_t>; static inline return_t __call( const T arg0 ) { return spirv:: bitCount<T>( arg0 ); }}; template<typename UInt64> struct find_msb_helper<UInt64 ,::nbl::hlsl::enable_if_t<(is_same_v<UInt64, uint64_t>),void> > { using return_t = int32_t; static return_t __call(const in UInt64 val) { const uint32_t highBits = uint32_t(val >> 32); const int32_t highMsb = find_msb_helper<uint32_t>::__call(highBits); if (highMsb == -1) { const uint32_t lowBits = uint32_t(val); const int32_t lowMsb = find_msb_helper<uint32_t>::__call(lowBits); if (lowMsb == -1) return -1; return lowMsb; } return highMsb + 32; } }; template<typename UInt64> struct find_lsb_helper<UInt64 ,::nbl::hlsl::enable_if_t<(is_same_v<UInt64, uint64_t>),void> > { static int32_t __call(const in uint64_t val) { const uint32_t lowBits = uint32_t(val); const int32_t lowLsb = find_lsb_helper<uint32_t>::__call(lowBits); if (lowLsb == -1) { const uint32_t highBits = uint32_t(val >> 32); const int32_t highLsb = find_lsb_helper<uint32_t>::__call(highBits); if (highLsb == -1) return -1; else return 32 + highLsb; } return lowLsb; } }; template<typename SquareMatrix> struct inverse_helper<SquareMatrix ,::nbl::hlsl::enable_if_t<(concepts::Matrix<SquareMatrix>&& matrix_traits<SquareMatrix>::Square),void> > { static SquareMatrix __call(const in SquareMatrix mat) { return spirv::matrixInverse<SquareMatrix>(mat); } }; template<typename T> struct mix_helper<T, T ,::nbl::hlsl::enable_if_t<(always_true<__decltype(spirv::fMix<T>(experimental::declval<T>(), experimental::declval<T>(), experimental::declval<T>()))>),void> > { using return_t = conditional_t<is_vector_v<T>, vector<typename vector_traits<T>::scalar_type, vector_traits<T>::Dimension>, T>; static inline return_t __call(const T x, const T y, const T a) { return spirv::fMix<T>(x, y, a); } }; template<typename T, typename U> struct mix_helper<T, U ,::nbl::hlsl::enable_if_t<((concepts::Scalar<T> || concepts::Vectorial<T>) && !concepts::Boolean<T> && concepts::Boolean<U>),void> > { using return_t = conditional_t<is_vector_v<T>, vector<typename vector_traits<T>::scalar_type, vector_traits<T>::Dimension>, T>; // for a component of a that is false, the corresponding component of x is returned // for a component of a that is true, the corresponding component of y is returned // so we make sure this is correct when calling the operation static inline return_t __call(const T x, const T y, const U a) { return spirv::select<T, U>(a, y, x); } }; template<typename SquareMatrix> struct determinant_helper<SquareMatrix ,::nbl::hlsl::enable_if_t<(matrix_traits<SquareMatrix>::Square),void> > { static typename matrix_traits<SquareMatrix>::scalar_type __call(const in SquareMatrix mat) { return spirv::determinant<SquareMatrix>(mat); } }; template<typename T> struct cross_helper<T ,::nbl::hlsl::enable_if_t<(concepts::FloatingPointVector<T> && (vector_traits<T>::Dimension == 3)),void> > { static T __call(const in T lhs, const in T rhs) { return spirv::cross<T>(lhs, rhs); } }; #line 701 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl" // C++ and HLSL specializations template<typename T> struct bitReverseAs_helper<T ,::nbl::hlsl::enable_if_t<(concepts::UnsignedIntegralScalar<T>),void> > { static T __call(const in T val, uint16_t bits) { return bitReverse_helper<T>::__call(val) >> promote<T, scalar_type_t<T> >(scalar_type_t <T>(sizeof(T) * 8 - bits)); } }; // SPIR-V already defines specializations for builtin vector types #line 720 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl" template<typename T> struct clamp_helper<T ,::nbl::hlsl::enable_if_t<(concepts::Vectorial<T> && !is_vector_v<T>),void> > { using return_t = T; static return_t __call(const in T val, const in T min, const in T max) { using traits = hlsl::vector_traits<T>; array_get<T, typename traits::scalar_type> getter; array_set<return_t, typename traits::scalar_type> setter; return_t output; for (uint32_t i = 0; i < traits::Dimension; ++i) setter(output, i, clamp_helper<typename traits::scalar_type>::__call(getter(val, i), getter(min, i), getter(max, i))); return output; } }; template<typename T> struct cross_helper<T ,::nbl::hlsl::enable_if_t<(concepts::Vectorial<T> && !is_vector_v<T> && concepts::Vectorial<T> && (vector_traits<T>::Dimension == 3)),void> > { static T __call(const in T lhs, const in T rhs) { using traits = hlsl::vector_traits<T>; array_get<T, typename traits::scalar_type> getter; array_set<T, typename traits::scalar_type> setter; T output; setter(output, 0, getter(lhs, 1) * getter(rhs, 2) - getter(rhs, 1) * getter(lhs, 2)); setter(output, 1, getter(lhs, 2) * getter(rhs, 0) - getter(rhs, 2) * getter(lhs, 0)); setter(output, 2, getter(lhs, 0) * getter(rhs, 1) - getter(rhs, 0) * getter(lhs, 1)); return output; } }; template<typename T> struct min_helper<T ,::nbl::hlsl::enable_if_t<(concepts::Vectorial<T> && !is_vector_v<T>),void> > { static T __call(const in T a, const in T b) { using traits = hlsl::vector_traits<T>; array_get<T, typename traits::scalar_type> getter; array_set<T, typename traits::scalar_type> setter; T output; for (uint32_t i = 0; i < traits::Dimension; ++i) setter(output, i, min_helper<typename traits::scalar_type>::__call(getter(a, i), getter(b, i))); return output; } }; template<typename T> struct max_helper<T ,::nbl::hlsl::enable_if_t<(concepts::Vectorial<T> && !is_vector_v<T>),void> > { static T __call(const in T a, const in T b) { using traits = hlsl::vector_traits<T>; array_get<T, typename traits::scalar_type> getter; array_set<T, typename traits::scalar_type> setter; T output; for (uint32_t i = 0; i < traits::Dimension; ++i) setter(output, i, max_helper<typename traits::scalar_type>::__call(getter(a, i), getter(b, i))); return output; } }; template<typename LhsT, typename RhsT> struct mul_helper<LhsT, RhsT ,::nbl::hlsl::enable_if_t<(concepts::Matrix<LhsT> && concepts::Vector<RhsT> && (matrix_traits<LhsT>::ColumnCount == vector_traits<RhsT>::Dimension)),void> > { using lhs_traits = matrix_traits<LhsT>; using rhs_traits = vector_traits<RhsT>; using return_t = vector<typename lhs_traits::scalar_type, lhs_traits::RowCount>; static inline return_t __call(LhsT lhs, RhsT rhs) { return mul(lhs, rhs); } }; template<typename LhsT, typename RhsT> struct mul_helper<LhsT, RhsT ,::nbl::hlsl::enable_if_t<(concepts::Matrix<LhsT> && concepts::Matrix<RhsT> && (matrix_traits<LhsT>::ColumnCount == matrix_traits<RhsT>::RowCount)),void> > { using lhs_traits = matrix_traits<LhsT>; using rhs_traits = matrix_traits<RhsT>; using return_t = matrix<typename lhs_traits::scalar_type, lhs_traits::RowCount, rhs_traits::ColumnCount>; static inline return_t __call(LhsT lhs, RhsT rhs) { return mul(lhs, rhs); } }; #line 840 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl" template<typename T>struct rsqrt_helper<T ,::nbl::hlsl::enable_if_t<( concepts::FloatingPointVectorial<T> && concepts::Vectorial<T> && !is_vector_v<T>),void> >{ using return_t = T; static return_t __call(const in T vec) { using traits = hlsl::vector_traits<T>; using return_t_traits = hlsl::vector_traits<return_t>; array_get<T, typename traits::scalar_type> getter; array_set<return_t, typename return_t_traits::scalar_type> setter; return_t output; for (uint32_t i = 0; i < traits::Dimension; ++i) setter(output, i, rsqrt_helper<typename traits::scalar_type>::__call(getter(vec, i))); return output; }}; template<typename T>struct bitReverse_helper<T ,::nbl::hlsl::enable_if_t<( concepts::Vectorial<T> && !is_vector_v<T>),void> >{ using return_t = T; static return_t __call(const in T vec) { using traits = hlsl::vector_traits<T>; using return_t_traits = hlsl::vector_traits<return_t>; array_get<T, typename traits::scalar_type> getter; array_set<return_t, typename return_t_traits::scalar_type> setter; return_t output; for (uint32_t i = 0; i < traits::Dimension; ++i) setter(output, i, bitReverse_helper<typename traits::scalar_type>::__call(getter(vec, i))); return output; }}; template<typename T>struct fract_helper<T ,::nbl::hlsl::enable_if_t<( concepts::Vectorial<T> && !is_vector_v<T>),void> >{ using return_t = T; static return_t __call(const in T vec) { using traits = hlsl::vector_traits<T>; using return_t_traits = hlsl::vector_traits<return_t>; array_get<T, typename traits::scalar_type> getter; array_set<return_t, typename return_t_traits::scalar_type> setter; return_t output; for (uint32_t i = 0; i < traits::Dimension; ++i) setter(output, i, fract_helper<typename traits::scalar_type>::__call(getter(vec, i))); return output; }}; template<typename T>struct sign_helper<T ,::nbl::hlsl::enable_if_t<( concepts::Vectorial<T> && !is_vector_v<T>),void> >{ using return_t = T; static return_t __call(const in T vec) { using traits = hlsl::vector_traits<T>; using return_t_traits = hlsl::vector_traits<return_t>; array_get<T, typename traits::scalar_type> getter; array_set<return_t, typename return_t_traits::scalar_type> setter; return_t output; for (uint32_t i = 0; i < traits::Dimension; ++i) setter(output, i, sign_helper<typename traits::scalar_type>::__call(getter(vec, i))); return output; }}; template<typename T>struct degrees_helper<T ,::nbl::hlsl::enable_if_t<( concepts::Vectorial<T> && !is_vector_v<T>),void> >{ using return_t = T; static return_t __call(const in T vec) { using traits = hlsl::vector_traits<T>; using return_t_traits = hlsl::vector_traits<return_t>; array_get<T, typename traits::scalar_type> getter; array_set<return_t, typename return_t_traits::scalar_type> setter; return_t output; for (uint32_t i = 0; i < traits::Dimension; ++i) setter(output, i, degrees_helper<typename traits::scalar_type>::__call(getter(vec, i))); return output; }}; template<typename T>struct radians_helper<T ,::nbl::hlsl::enable_if_t<( concepts::Vectorial<T> && !is_vector_v<T>),void> >{ using return_t = T; static return_t __call(const in T vec) { using traits = hlsl::vector_traits<T>; using return_t_traits = hlsl::vector_traits<return_t>; array_get<T, typename traits::scalar_type> getter; array_set<return_t, typename return_t_traits::scalar_type> setter; return_t output; for (uint32_t i = 0; i < traits::Dimension; ++i) setter(output, i, radians_helper<typename traits::scalar_type>::__call(getter(vec, i))); return output; }}; template<typename T>struct bitCount_helper<T ,::nbl::hlsl::enable_if_t<( concepts::Vectorial<T> && !is_vector_v<T>),void> >{ using return_t = vector<int32_t, hlsl::vector_traits<T>::Dimension>; static return_t __call(const in T vec) { using traits = hlsl::vector_traits<T>; using return_t_traits = hlsl::vector_traits<return_t>; array_get<T, typename traits::scalar_type> getter; array_set<return_t, typename return_t_traits::scalar_type> setter; return_t output; for (uint32_t i = 0; i < traits::Dimension; ++i) setter(output, i, bitCount_helper<typename traits::scalar_type>::__call(getter(vec, i))); return output; }}; template<typename T>struct find_msb_helper<T ,::nbl::hlsl::enable_if_t<( concepts::Vectorial<T> && !is_vector_v<T>),void> >{ using return_t = vector<int32_t, hlsl::vector_traits<T>::Dimension>; static return_t __call(const in T vec) { using traits = hlsl::vector_traits<T>; using return_t_traits = hlsl::vector_traits<return_t>; array_get<T, typename traits::scalar_type> getter; array_set<return_t, typename return_t_traits::scalar_type> setter; return_t output; for (uint32_t i = 0; i < traits::Dimension; ++i) setter(output, i, find_msb_helper<typename traits::scalar_type>::__call(getter(vec, i))); return output; }}; template<typename T>struct find_lsb_helper<T ,::nbl::hlsl::enable_if_t<( concepts::Vectorial<T> && !is_vector_v<T>),void> >{ using return_t = vector<int32_t, hlsl::vector_traits<T>::Dimension>; static return_t __call(const in T vec) { using traits = hlsl::vector_traits<T>; using return_t_traits = hlsl::vector_traits<return_t>; array_get<T, typename traits::scalar_type> getter; array_set<return_t, typename return_t_traits::scalar_type> setter; return_t output; for (uint32_t i = 0; i < traits::Dimension; ++i) setter(output, i, find_lsb_helper<typename traits::scalar_type>::__call(getter(vec, i))); return output; }}; template<typename T>struct nMin_helper<T ,::nbl::hlsl::enable_if_t<( concepts::Vectorial<T> && !is_vector_v<T>),void> >{ using return_t = T; static return_t __call(const in T vec) { using traits = hlsl::vector_traits<T>; using return_t_traits = hlsl::vector_traits<return_t>; array_get<T, typename traits::scalar_type> getter; array_set<return_t, typename return_t_traits::scalar_type> setter; return_t output; for (uint32_t i = 0; i < traits::Dimension; ++i) setter(output, i, nMin_helper<typename traits::scalar_type>::__call(getter(vec, i))); return output; }}; template<typename T>struct nMax_helper<T ,::nbl::hlsl::enable_if_t<( concepts::Vectorial<T> && !is_vector_v<T>),void> >{ using return_t = T; static return_t __call(const in T vec) { using traits = hlsl::vector_traits<T>; using return_t_traits = hlsl::vector_traits<return_t>; array_get<T, typename traits::scalar_type> getter; array_set<return_t, typename return_t_traits::scalar_type> setter; return_t output; for (uint32_t i = 0; i < traits::Dimension; ++i) setter(output, i, nMax_helper<typename traits::scalar_type>::__call(getter(vec, i))); return output; }}; template<typename T> struct all_helper<T ,::nbl::hlsl::enable_if_t<(concepts::Vectorial<T> && !is_vector_v<T>&& is_same_v<typename vector_traits<T>::scalar_type, bool>),void> > { static bool __call(const in T x) { using traits = hlsl::vector_traits<T>; array_get<T, typename traits::scalar_type> getter; array_set<T, typename traits::scalar_type> setter; bool output = true; for (uint32_t i = 0; i < traits::Dimension; ++i) output = output && getter(x, i); return output; } }; template<typename T> struct any_helper<T ,::nbl::hlsl::enable_if_t<(concepts::Vectorial<T> && !is_vector_v<T> && is_same_v<typename vector_traits<T>::scalar_type, bool>),void> > { static bool __call(const in T x) { using traits = hlsl::vector_traits<T>; array_get<T, typename traits::scalar_type> getter; array_set<T, typename traits::scalar_type> setter; bool output = false; for (uint32_t i = 0; i < traits::Dimension; ++i) output = output || getter(x, i); return output; } }; template<typename T> struct step_helper<T ,::nbl::hlsl::enable_if_t<(concepts::Vectorial<T> && !is_vector_v<T>),void> > { using return_t = T; static return_t __call(const in T edge, const in T x) { using traits = hlsl::vector_traits<T>; array_get<T, typename traits::scalar_type> getter; array_set<return_t, typename traits::scalar_type> setter; return_t output; for (uint32_t i = 0; i < traits::Dimension; ++i) setter(output, i, step_helper<typename traits::scalar_type>::__call(getter(edge, i), getter(x, i))); return output; } }; template<typename T> struct smoothStep_helper<T ,::nbl::hlsl::enable_if_t<(concepts::Vectorial<T> && !is_vector_v<T>),void> > { using return_t = T; static return_t __call(const in T edge0, const in T edge1, const in T x) { using traits = hlsl::vector_traits<T>; array_get<T, typename traits::scalar_type> getter; array_set<return_t, typename traits::scalar_type> setter; return_t output; for (uint32_t i = 0; i < traits::Dimension; ++i) setter(output, i, smoothStep_helper<typename traits::scalar_type>::__call(getter(edge0, i), getter(edge1, i), getter(x, i))); return output; } }; template<typename T> struct mix_helper<T, T ,::nbl::hlsl::enable_if_t<(concepts::Vectorial<T> && !is_vector_v<T>),void> > { using return_t = T; static return_t __call(const in T x, const in T y, const in T a) { using traits = hlsl::vector_traits<T>; array_get<T, typename traits::scalar_type> getter; array_set<return_t, typename traits::scalar_type> setter; return_t output; for (uint32_t i = 0; i < traits::Dimension; ++i) setter(output, i, mix_helper<typename traits::scalar_type, typename traits::scalar_type>::__call(getter(x, i), getter(y, i), getter(a, i))); return output; } }; template<typename T, typename U> struct mix_helper<T, U ,::nbl::hlsl::enable_if_t<(concepts::Vectorial<T> && !is_vector_v<T> && concepts::Boolean<U> && vector_traits<T>::Dimension == vector_traits<U>::Dimension),void> > { using return_t = T; static return_t __call(const in T x, const in T y, const in U a) { using traitsT = hlsl::vector_traits<T>; using traitsU = hlsl::vector_traits<U>; array_get<T, typename traitsT::scalar_type> getterT; array_get<U, typename traitsU::scalar_type> getterU; array_set<return_t, typename traitsT::scalar_type> setter; return_t output; for (uint32_t i = 0; i < traitsT::Dimension; ++i) setter(output, i, mix_helper<typename traitsT::scalar_type, typename traitsU::scalar_type>::__call(getterT(x, i), getterT(y, i), getterU(a, i))); return output; } }; template<typename T> struct fma_helper<T ,::nbl::hlsl::enable_if_t<(concepts::Vectorial<T> && !is_vector_v<T>),void> > { using return_t = T; static return_t __call(const in T x, const in T y, const in T z) { using traits = hlsl::vector_traits<T>; array_get<T, typename traits::scalar_type> getter; array_set<T, typename traits::scalar_type> setter; return_t output; for (uint32_t i = 0; i < traits::Dimension; ++i) setter(output, i, fma_helper<typename traits::scalar_type>::__call(getter(x, i), getter(y, i), getter(z, i))); return output; } }; #line 994 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl" template<typename Vectorial> struct dot_helper<Vectorial ,::nbl::hlsl::enable_if_t<((concepts::Vectorial<Vectorial> && !is_vector_v<Vectorial>) && concepts::FloatingPoint<Vectorial>),void> > { using scalar_type = typename vector_traits<Vectorial>::scalar_type; static inline scalar_type __call(const in Vectorial lhs, const in Vectorial rhs) { static const uint32_t ArrayDim = vector_traits<Vectorial>::Dimension; static array_get<Vectorial, scalar_type> getter; scalar_type retval = getter(lhs, 0) * getter(rhs, 0); for (uint32_t i = 1; i < ArrayDim; ++i) retval = fma_helper<scalar_type>::__call(getter(lhs, i), getter(rhs, i), retval); return retval; } }; template<typename Vectorial> struct dot_helper<Vectorial ,::nbl::hlsl::enable_if_t<((concepts::Vectorial<Vectorial> && !is_vector_v<Vectorial>) && !concepts::FloatingPoint<Vectorial>),void> > { using scalar_type = typename vector_traits<Vectorial>::scalar_type; static inline scalar_type __call(const in Vectorial lhs, const in Vectorial rhs) { static const uint32_t ArrayDim = vector_traits<Vectorial>::Dimension; static array_get<Vectorial, scalar_type> getter; scalar_type retval = getter(lhs, 0) * getter(rhs, 0); for (uint32_t i = 1; i < ArrayDim; ++i) retval = retval + getter(lhs, i) * getter(rhs, i); return retval; } }; } } } #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts/core.hlsl" // Copyright (C) 2024-2025 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts/vector.hlsl" // Copyright (C) 2024-2025 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts/matrix.hlsl" // Copyright (C) 2024-2025 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 21 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl" namespace nbl { namespace hlsl { template<typename T> inline T undef() { return cpp_compat_intrinsics_impl::undef_helper<T>::__call(); } template<typename T> inline typename cpp_compat_intrinsics_impl::bitCount_helper<T>::return_t bitCount(const in T val) { return cpp_compat_intrinsics_impl::bitCount_helper<T>::__call(val); } template<typename T> T cross(const in T lhs, const in T rhs) { return cpp_compat_intrinsics_impl::cross_helper<T>::__call(lhs, rhs); } template<typename T> typename cpp_compat_intrinsics_impl::clamp_helper<T>::return_t clamp(const in T val, const in T _min, const in T _max) { return cpp_compat_intrinsics_impl::clamp_helper<T>::__call(val, _min, _max); } template<typename FloatingPointVectorial> typename vector_traits<FloatingPointVectorial>::scalar_type length(const in FloatingPointVectorial vec) { return cpp_compat_intrinsics_impl::length_helper<FloatingPointVectorial>::__call(vec); } template<typename FloatingPointVectorial> FloatingPointVectorial normalize(const in FloatingPointVectorial vec) { return cpp_compat_intrinsics_impl::normalize_helper<FloatingPointVectorial>::__call(vec); } template<typename Vectorial> typename vector_traits<Vectorial>::scalar_type dot(const in Vectorial lhs, const in Vectorial rhs) { return cpp_compat_intrinsics_impl::dot_helper<Vectorial>::__call(lhs, rhs); } // determinant not defined cause its implemented via hidden friend // https://stackoverflow.com/questions/67459950/why-is-a-friend-function-not-treated-as-a-member-of-a-namespace-of-a-class-it-wa template<typename Matrix ,::nbl::hlsl::enable_if_t<(concepts::Matricial<Matrix>),bool> = true> inline typename matrix_traits<Matrix>::scalar_type determinant(const in Matrix mat) { return cpp_compat_intrinsics_impl::determinant_helper<Matrix>::__call(mat); } template<typename T> inline typename cpp_compat_intrinsics_impl::find_lsb_helper<T>::return_t findLSB(const in T val) { return cpp_compat_intrinsics_impl::find_lsb_helper<T>::__call(val); } template<typename T> inline typename cpp_compat_intrinsics_impl::find_msb_helper<T>::return_t findMSB(const in T val) { return cpp_compat_intrinsics_impl::find_msb_helper<T>::__call(val); } // inverse not defined cause its implemented via hidden friend template<typename Matrix ,::nbl::hlsl::enable_if_t<(concepts::Matricial<Matrix>),bool> = true> inline Matrix inverse(const in Matrix mat) { return cpp_compat_intrinsics_impl::inverse_helper<Matrix>::__call(mat); } // transpose not defined cause its implemented via hidden friend template<typename Matrix ,::nbl::hlsl::enable_if_t<(concepts::Matricial<Matrix>),bool> = true> inline typename matrix_traits<Matrix>::transposed_type transpose(const in Matrix m) { return cpp_compat_intrinsics_impl::transpose_helper<Matrix>::__call(m); } template<typename LhsT, typename RhsT> inline typename cpp_compat_intrinsics_impl::mul_helper<LhsT, RhsT>::return_t mul(LhsT lhs, RhsT rhs) { return cpp_compat_intrinsics_impl::mul_helper<LhsT, RhsT>::__call(lhs, rhs); } template<typename T> inline T min(const in T a, const in T b) { return cpp_compat_intrinsics_impl::min_helper<T>::__call(a, b); } template<typename T> inline T max(const in T a, const in T b) { return cpp_compat_intrinsics_impl::max_helper<T>::__call(a, b); } template<typename FloatingPoint> inline FloatingPoint rsqrt(FloatingPoint x) { return cpp_compat_intrinsics_impl::rsqrt_helper<FloatingPoint>::__call(x); } template<typename Integer> inline Integer bitReverse(Integer val) { return cpp_compat_intrinsics_impl::bitReverse_helper<Integer>::__call(val); } template<typename T ,::nbl::hlsl::enable_if_t<(is_unsigned_v<T>),bool> = true> /** * @brief Takes the binary representation of `value` and returns a value of the same type resulting from reversing the string of bits as if it was `bits` long. * Keep in mind `bits` cannot exceed `8 * sizeof(T)`. * * @tparam T type of the value to operate on. * * @param [in] value The value to bitreverse. * @param [in] bits The length of the string of bits used to represent `value`. */ T bitReverseAs(T val, uint16_t bits) { return cpp_compat_intrinsics_impl::bitReverseAs_helper<T>::__call(val, bits); } template<typename Vector> inline bool all(Vector vec) { return cpp_compat_intrinsics_impl::all_helper<Vector>::__call(vec); } template<typename Vector> inline bool any(Vector vec) { return cpp_compat_intrinsics_impl::any_helper<Vector>::__call(vec); } template<typename Condition, typename ResultType> inline ResultType select(Condition condition, ResultType object1, ResultType object2) { return cpp_compat_intrinsics_impl::select_helper<Condition, ResultType>::__call(condition, object1, object2); } /** * @brief Returns x - floor(x). * * @tparam T type of the value to operate on. * * @param [in] val The value to operate on. */ template<typename T> inline T fract(const in T val) { return cpp_compat_intrinsics_impl::fract_helper<T>::__call(val); } template<typename T, typename U> inline T mix(const in T x, const in T y, const in U a) { return cpp_compat_intrinsics_impl::mix_helper<T, U>::__call(x, y, a); } template<typename T> inline T sign(const in T val) { return cpp_compat_intrinsics_impl::sign_helper<T>::__call(val); } template<typename T> inline T radians(const in T degrees) { return cpp_compat_intrinsics_impl::radians_helper<T>::__call(degrees); } template<typename T> inline T degrees(const in T radians) { return cpp_compat_intrinsics_impl::degrees_helper<T>::__call(radians); } template<typename T> inline T step(const in T edge, const in T x) { return cpp_compat_intrinsics_impl::step_helper<T>::__call(edge, x); } template<typename T> inline T smoothStep(const in T edge0, const in T edge1, const in T x) { return cpp_compat_intrinsics_impl::smoothStep_helper<T>::__call(edge0, edge1, x); } template<typename T> inline T faceForward(const in T N, const in T I, const in T Nref) { return cpp_compat_intrinsics_impl::faceForward_helper<T>::__call(N, I, Nref); } template<typename T> inline T reflect(const in T I, const in T N) { return cpp_compat_intrinsics_impl::reflect_helper<T>::__call(I, N); } template<typename T, typename U> inline T refract(const in T I, const in T N, const in U eta) { return cpp_compat_intrinsics_impl::refract_helper<T, U>::__call(I, N, eta); } template<typename T> inline spirv::AddCarryOutput<T> addCarry(const in T operand1, const in T operand2) { return cpp_compat_intrinsics_impl::addCarry_helper<T>::__call(operand1, operand2); } template<typename T> inline spirv::SubBorrowOutput<T> subBorrow(const in T operand1, const in T operand2) { return cpp_compat_intrinsics_impl::subBorrow_helper<T>::__call(operand1, operand2); } #line 251 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl" template<typename T ,::nbl::hlsl::enable_if_t<(is_same_v<T, float32_t4>),bool> = true> inline int32_t packSnorm4x8(T vec) { return spirv::packSnorm4x8(vec); } template<typename T ,::nbl::hlsl::enable_if_t<(is_same_v<T, float32_t4>),bool> = true> inline int32_t packUnorm4x8(T vec) { return spirv::packUnorm4x8(vec); } template<typename T ,::nbl::hlsl::enable_if_t<(is_same_v<T, float32_t2>),bool> = true> inline int32_t packSnorm2x16(T vec) { return spirv::packSnorm2x16(vec); } template<typename T ,::nbl::hlsl::enable_if_t<(is_same_v<T, float32_t2>),bool> = true> inline int32_t packUnorm2x16(T vec) { return spirv::packUnorm2x16(vec); } template<typename T ,::nbl::hlsl::enable_if_t<(is_same_v<T, float32_t2>),bool> = true> inline int32_t packHalf2x16(T vec) { return spirv::packHalf2x16(vec); } template<typename T ,::nbl::hlsl::enable_if_t<(is_same_v<T, int32_t2>),bool> = true> inline float64_t packDouble2x32(T vec) { return spirv::packDouble2x32(vec); } template<typename T ,::nbl::hlsl::enable_if_t<(is_same_v<T, int32_t>),bool> = true> inline float32_t2 unpackSnorm2x16(T val) { return spirv::unpackSnorm2x16(val); } template<typename T ,::nbl::hlsl::enable_if_t<(is_same_v<T, int32_t>),bool> = true> inline float32_t2 unpackUnorm2x16(T val) { return spirv::unpackUnorm2x16(val); } template<typename T ,::nbl::hlsl::enable_if_t<(is_same_v<T, int32_t>),bool> = true> inline float32_t2 unpackHalf2x16(T val) { return spirv::unpackHalf2x16(val); } template<typename T ,::nbl::hlsl::enable_if_t<(is_same_v<T, int32_t>),bool> = true> inline float32_t4 unpackSnorm4x8(T val) { return spirv::unpackSnorm4x8(val); } template<typename T ,::nbl::hlsl::enable_if_t<(is_same_v<T, int32_t>),bool> = true> inline float32_t4 unpackUnorm4x8(T val) { return spirv::unpackUnorm4x8(val); } template<typename T ,::nbl::hlsl::enable_if_t<(is_same_v<T, float64_t>),bool> = true> inline int32_t2 unpackDouble2x32(T val) { return spirv::unpackDouble2x32(val); } template<typename T> inline T fma(const in T x, const in T y, const in T z) { return cpp_compat_intrinsics_impl::fma_helper<T>::__call(x, y, z); } } } #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/type_traits.hlsl" // Copyright (C) 2022 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts/core.hlsl" // Copyright (C) 2024-2025 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 7 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/cpp_compat/truncate.hlsl" namespace nbl { namespace hlsl { namespace impl { template<typename T, typename U ,typename __requires=void > struct Truncate { inline T operator()(const in U v) { return T(v); } }; template<typename Scalar, uint16_t N> struct Truncate<vector<Scalar, 1>, vector<Scalar, N> ,::nbl::hlsl::enable_if_t<(concepts::Scalar<Scalar>),void> > { inline vector<Scalar, 1> operator()(const in vector<Scalar, N> v) { vector<Scalar, 1> truncated = { v[0] }; return truncated; } }; template<typename Scalar, uint16_t N> struct Truncate<vector<Scalar, 2>, vector<Scalar, N> ,::nbl::hlsl::enable_if_t<(concepts::Scalar<Scalar> && N >= 2),void> > { inline vector<Scalar, 2> operator()(const in vector<Scalar, N> v) { vector<Scalar, 2> truncated = { v[0], v[1]}; return truncated; } }; template<typename Scalar, uint16_t N> struct Truncate<vector<Scalar, 3>, vector<Scalar, N> ,::nbl::hlsl::enable_if_t<(concepts::Scalar<Scalar>&& N >= 3),void> > { inline vector<Scalar, 3> operator()(const in vector<Scalar, N> v) { vector<Scalar, 3> truncated = { v[0], v[1], v[2] }; return truncated; } }; template<typename Scalar, uint16_t N> struct Truncate<vector<Scalar, 4>, vector<Scalar, N> ,::nbl::hlsl::enable_if_t<(concepts::Scalar<Scalar>&& N >= 4),void> > { inline vector<Scalar, 4> operator()(const in vector<Scalar, N> v) { vector<Scalar, 4> truncated = { v[0], v[1], v[2], v[3] }; return truncated; } }; } //namespace impl template<typename T, typename U> inline T truncate(const in U v) { impl::Truncate<T, U> _truncate; return _truncate(v); } } } #line 10 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/cpp_compat.hlsl" // Had to push some stuff here to avoid circular dependencies #line 3 "C:/Users/Rynair/Desktop/Nabla/examples_tests/11_FFT/app_resources/common.hlsl" using scalar_t = nbl::hlsl::float32_t; struct PushConstantData { uint64_t deviceBufferAddress; }; const static uint32_t WorkgroupSizeLog2 = 6; const static uint32_t ElementsPerThreadLog2 = 3; const static uint32_t complexElementCount = uint32_t(1) << (WorkgroupSizeLog2 + ElementsPerThreadLog2); #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts.hlsl" // Copyright (C) 2023-2024 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/complex.hlsl" // Copyright (C) 2023 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/functional.hlsl" // Copyright (C) 2023 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/glsl_compat/core.hlsl" // Copyright (C) 2023 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/limits.hlsl" // Copyright (C) 2022 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/macros.h" // Copyright (C) 2022 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/type_traits.hlsl" // Copyright (C) 2022 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/macros.h" // Copyright (C) 2022 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 12 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/limits.hlsl" // C++ headers #line 18 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/limits.hlsl" /* nuumeric_limits C++ API spec elements: is_specialized is_signed is_integer is_exact has_infinity has_quiet_NaN has_signaling_NaN has_denorm has_denorm_loss round_style is_iec559 is_bounded is_modulo digits digits10 max_digits10 radix min_exponent min_exponent10 max_exponent max_exponent10 traps tinyness_before min max lowest epsilon round_error infinity quiet_NaN signaling_NaN denorm_min */ namespace nbl { namespace hlsl { enum float_denorm_style { denorm_indeterminate = -1, denorm_absent = 0, denorm_present = 1 }; enum float_round_style { round_indeterminate = -1, round_toward_zero = 0, round_to_nearest = 1, round_toward_infinity = 2, round_toward_neg_infinity = 3 }; #line 82 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/limits.hlsl" // Overlapping definitions // Below implementations are not intended to be used on C++ side namespace impl { template<class T> struct num_base : type_identity<T> { const static int32_t size = sizeof(T); const static int32_t S8 = size; const static int32_t S16 = size / 2; const static int32_t S32 = size / 4; const static int32_t S64 = size / 8; /* float_digits_array = {11, 24, 53}; float_digits = float_digits_array[fp_idx]; */ const static int32_t float_digits = 11*S16 + 2*S32 + 5*S64; /* decimal_digits_array = floor((float_digits_array-1)*log2) = {3, 6, 15}; float_decimal_digits = decimal_digits_array[fp_idx]; */ const static int32_t float_decimal_digits = 3*(S16 + S64); /* decimal_max_digits_array = ceil(float_digits_array*log2 + 1) = {5, 9, 17}; float_decimal_max_digits = decimal_max_digits_array[fp_idx]; */ const static int32_t float_decimal_max_digits = 5*S16 - S32 - S64; /* min_decimal_exponent_array = ceil((float_min_exponent-1) * log2) = { -4, -37, -307 }; float_min_decimal_exponent = min_decimal_exponent_array[fp_idx]; */ const static int32_t float_min_decimal_exponent = -4*S16 - 29*S32 - 233*S64; /* max_decimal_exponent_array = floor(float_max_exponent * log2) = { 4, 38, 308 }; float_max_decimal_exponent = max_decimal_exponent_array[fp_idx]; */ const static int32_t float_max_decimal_exponent = 4*S16 + 30*S32 + 232*S64; const static int32_t float_exponent_bits = 8 * size - 1 - (float_digits-1); const static int32_t float_max_exponent = 1 << (float_exponent_bits-1); const static int32_t float_min_exponent = 3 - float_max_exponent; const static bool is_bool = is_same<T, bool>::value; // identifies types for which std::numeric_limits is specialized const static bool is_specialized = true; // identifies signed types const static bool is_signed = nbl::hlsl::is_signed<T>::value; // identifies integer types const static bool is_integer = is_integral<T>::value; // identifies exact types const static bool is_exact = is_integer; // identifies floating-point types that can represent the special value "positive infinity" const static bool has_infinity = !is_integer; // (TODO) think about what this means for HLSL // identifies floating-point types that can represent the special value "quiet not-a-number" (NaN) const static bool has_quiet_NaN = !is_integer; // identifies floating-point types that can represent the special value "signaling not-a-number" (NaN) const static bool has_signaling_NaN = !is_integer; // identifies the denormalization style used by the floating-point type const static float_denorm_style has_denorm = is_integer ? float_denorm_style::denorm_absent : float_denorm_style::denorm_present; // identifies the floating-point types that detect loss of precision as denormalization loss rather than inexact result const static bool has_denorm_loss = false; // identifies the rounding style used by the type const static float_round_style round_style = is_integer ? float_round_style::round_toward_zero : float_round_style::round_to_nearest; // identifies the IEC 559/IEEE 754 floating-point types const static bool is_iec559 = !is_integer; // identifies types that represent a finite set of values const static bool is_bounded = true; // TODO verify this // identifies types that handle overflows with modulo arithmetic const static bool is_modulo = is_integer && !is_signed && !is_bool; // number of radix digits that can be represented without change const static int32_t digits = is_integer ? (is_bool? 1 : 8*size - is_signed) : float_digits; // number of decimal digits that can be represented without change const static int32_t digits10 = is_integer ? (is_bool ? 0 : S8 * 2 + S32 + int32_t(!is_signed) * S64) : float_decimal_digits; // number of decimal digits necessary to differentiate all values of this type const static int32_t max_digits10 = !is_integer ? float_decimal_max_digits : 0; // the radix or integer base used by the representation of the given type const static int32_t radix = 2; // one more than the smallest negative power of the radix that is a valid normalized floating-point value const static int32_t min_exponent = !is_integer ? float_min_exponent : 0; // the smallest negative power of ten that is a valid normalized floating-point value const static int32_t min_exponent10 = !is_integer ? float_min_decimal_exponent : 0; // one more than the largest integer power of the radix that is a valid finite floating-point value const static int32_t max_exponent = !is_integer ? float_max_exponent : 0; // the largest integer power of 10 that is a valid finite floating-point value const static int32_t max_exponent10 = !is_integer ? float_max_decimal_exponent : 0; // identifies types which can cause arithmetic operations to trap const static bool traps = false; // identifies floating-point types that detect tinyness before rounding const static bool tinyness_before = false; }; template<class T> struct num_traits : num_base<T> { // have to be weird like that to avoid a warning const static T min = T(num_base<T>::is_signed)<<(num_base<T>::is_signed ? num_base<T>::digits:0); // FIXME: Lots of warnings with `T=bool` const static T max = ~min; const static T denorm_min = T(0); const static T quiet_NaN = T(0); const static T signaling_NaN = T(0); const static T infinity = T(0); }; template<> struct num_traits<float16_t> : num_base<float16_t> { // since float16_t has no constexpr ctor we have to use float32_t constants on cpp side which is only needed for testing using type = float32_t #line 217 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/limits.hlsl" ; const static type min = 6.103515e-05F; const static type max = 65504.0F; const static type denorm_min = 5.96046448e-08F; const static uint16_t quiet_NaN = 0x7FFF; const static uint16_t signaling_NaN = 0x7DFF; const static uint16_t infinity = 0x7C00; }; template<> struct num_traits<float32_t> : num_base<float32_t> { const static float32_t max = 3.402823466e+38F; const static float32_t min = 1.175494351e-38F; const static float32_t denorm_min = 1.401298464e-45F; const static uint32_t quiet_NaN = 0x7FC00000u; const static uint32_t signaling_NaN = 0x7FC00001u; const static uint32_t infinity = 0x7F800000u; }; template<> struct num_traits<float64_t> : num_base<float64_t> { const static float64_t max = 1.7976931348623158e+308l; const static float64_t min = 2.2250738585072014e-308l; const static float64_t denorm_min = 4.9406564584124654e-324l; const static uint64_t quiet_NaN = 0x7FF8000000000000ull; const static uint64_t signaling_NaN = 0x7FF0000000000001ull; const static uint64_t infinity = 0x7FF0000000000000ull; }; template<class T> struct numeric_limits : num_traits<T> { using type = typename num_traits<T>::type; const static type lowest = num_traits<T>::is_integer ? num_traits<T>::min : -num_traits<T>::max; // FIXME: warning C4293 `<<`: shift count negative or too big (only when instantiating with `int8_t` const static type epsilon = num_traits<T>::is_integer ? type(0) : (type(1) / type(1ull<<(num_traits<T>::float_digits-1))); const static type round_error = type(num_traits<T>::is_iec559)/type(2.0); }; } template<class T> struct numeric_limits : impl::numeric_limits<T> {}; #line 287 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/limits.hlsl" } } #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts/vector.hlsl" // Copyright (C) 2024-2025 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 13 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/functional.hlsl" namespace nbl { namespace hlsl { template<uint32_t StorageClass, typename T> using __spv_ptr_t = spirv::pointer_t<StorageClass,T>; template<uint32_t StorageClass, typename T> [[vk::ext_instruction(spv::OpCopyObject)]] __spv_ptr_t<StorageClass,T> addrof([[vk::ext_reference]] T v); template<uint32_t StorageClass, typename T> struct reference_wrapper_base { using spv_ptr_t = __spv_ptr_t<StorageClass,T>; spv_ptr_t ptr; void __init(spv_ptr_t _ptr) { ptr = _ptr; } T load() { return spirv::load<T,spv_ptr_t>(ptr); } void store(const T val) { spirv::store<T,spv_ptr_t>(ptr,val); } // TODO: use the same defaults as `glsl::atomicAnd` template<uint32_t memoryScope, uint32_t memorySemantics, typename S=T> // TODO: instead of `is_scalar_v` we need a test on whether the `spirv::atomicAnd` expression is callable enable_if_t<is_same_v<S,T>&&is_scalar_v<S>,T> atomicAnd(const T value) { return spirv::atomicAnd<T,spv_ptr_t>(ptr,memoryScope,memorySemantics,value); } // TODO: generate Or,Xor through a macro // TODO: comp swap is special, has an extra parameter }; template<typename T> struct reference_wrapper_base<spv::StorageClassPhysicalStorageBuffer,T> { using spv_ptr_t = typename T::instead_use_nbl::hlsl::bda::__ref; // normally would have specializations of load and store }; // we need to explicitly white-list storage classes due to // https://github.com/microsoft/DirectXShaderCompiler/issues/6578#issuecomment-2297181671 template<uint32_t StorageClass, typename T> struct reference_wrapper : enable_if_t< is_same_v<StorageClass,spv::StorageClassInput>|| is_same_v<StorageClass,spv::StorageClassUniform>|| is_same_v<StorageClass,spv::StorageClassWorkgroup>|| is_same_v<StorageClass,spv::StorageClassPushConstant>|| is_same_v<StorageClass,spv::StorageClassImage>|| is_same_v<StorageClass,spv::StorageClassStorageBuffer>, reference_wrapper_base<StorageClass,T> > { }; // TODO: generate atomic Add,Sub,Min,Max through partial template specializations on T // TODO: partial specializations for T being a special SPIR-V type for image ops, etc. #line 99 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/functional.hlsl" template<typename T ,typename __requires=void > struct bit_and { using type_t = T; T operator()(const in T lhs, const in T rhs) { return lhs & rhs; } using scalar_t = typename scalar_type<T>::type; using bitfield_t = typename unsigned_integer_of_size<sizeof(scalar_t)>::type; _Static_assert(!is_floating_point<T>::value,"We cannot define the identity element properly, you can thank https://github.com/microsoft/DirectXShaderCompiler/issues/5868 !"); const static T identity = ~bitfield_t(0); // TODO: need a `all_components<T>` (not in cpp_compat) which can create vectors and matrices with all members set to scalar }; template<typename T ,typename __requires=void > struct bit_or { using type_t = T; T operator()(const in T lhs, const in T rhs) { return lhs | rhs; } const static T identity = T(0); }; template<typename T ,typename __requires=void > struct bit_xor { using type_t = T; T operator()(const in T lhs, const in T rhs) { return lhs ^ rhs; } const static T identity = T(0); }; template<typename T ,typename __requires=void > struct plus { using type_t = T; T operator()(const in T lhs, const in T rhs) { return lhs + rhs; } const static T identity = T(0); }; template<typename T ,typename __requires=void > struct minus { using type_t = T; T operator()(const in T lhs, const in T rhs) { return lhs - rhs; } const static T identity = T(0); }; template<typename T ,typename __requires=void > struct multiplies { using type_t = T; T operator()(const in T lhs, const in T rhs) { return lhs * rhs; } const static T identity = T(1); }; template<typename T ,typename __requires=void > struct divides { using type_t = T; T operator()(const in T lhs, const in T rhs) { return lhs / rhs; } const static T identity = T(1); }; #line 147 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/functional.hlsl" template<typename T ,typename __requires=void > struct bit_not { using type_t = T; T operator()(const in T operand) { return ~operand; } }; // The default version above only works for fundamental scalars, vectors and matrices. This is because you can't call `~x` unless `x` is one of the former. // Similarly, calling `x.operator~()` is not valid for the aforementioned, and only for types overriding this operator. So, we need a specialization. template<typename T> struct bit_not<T ,::nbl::hlsl::enable_if_t<(!(concepts::Scalar<T> || concepts::Vector<T> || concepts::Matrix<T>)),void> > { using type_t = T; T operator()(const in T operand) { return operand.operator~(); } }; template<typename T ,typename __requires=void > struct equal_to { using type_t = T; T operator()(const in T lhs, const in T rhs) { return lhs == rhs; } }; template<typename T ,typename __requires=void > struct not_equal_to { using type_t = T; T operator()(const in T lhs, const in T rhs) { return lhs != rhs; } }; template<typename T ,typename __requires=void > struct greater { using type_t = T; T operator()(const in T lhs, const in T rhs) { return lhs > rhs; } }; template<typename T ,typename __requires=void > struct less { using type_t = T; T operator()(const in T lhs, const in T rhs) { return lhs < rhs; } }; template<typename T ,typename __requires=void > struct greater_equal { using type_t = T; T operator()(const in T lhs, const in T rhs) { return lhs >= rhs; } }; template<typename T ,typename __requires=void > struct less_equal { using type_t = T; T operator()(const in T lhs, const in T rhs) { return lhs <= rhs; } }; // The above comparison operators return bool on STD, but in HLSL they're supposed to yield bool vectors, so here's a specialization so that they return `vector<bool, N>` for vectorial types // GLM doesn't have operators on vectors #line 211 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/functional.hlsl" template<typename T> struct equal_to <T ,::nbl::hlsl::enable_if_t<(concepts::Vectorial<T>),void> >{ using type_t = T; vector<bool, vector_traits<T>::Dimension> operator()(const in T lhs, const in T rhs) { return lhs == rhs; }}; template<typename T> struct not_equal_to <T ,::nbl::hlsl::enable_if_t<(concepts::Vectorial<T>),void> >{ using type_t = T; vector<bool, vector_traits<T>::Dimension> operator()(const in T lhs, const in T rhs) { return lhs != rhs; }}; template<typename T> struct greater <T ,::nbl::hlsl::enable_if_t<(concepts::Vectorial<T>),void> >{ using type_t = T; vector<bool, vector_traits<T>::Dimension> operator()(const in T lhs, const in T rhs) { return lhs > rhs; }}; template<typename T> struct less <T ,::nbl::hlsl::enable_if_t<(concepts::Vectorial<T>),void> >{ using type_t = T; vector<bool, vector_traits<T>::Dimension> operator()(const in T lhs, const in T rhs) { return lhs < rhs; }}; template<typename T> struct greater_equal <T ,::nbl::hlsl::enable_if_t<(concepts::Vectorial<T>),void> >{ using type_t = T; vector<bool, vector_traits<T>::Dimension> operator()(const in T lhs, const in T rhs) { return lhs >= rhs; }}; template<typename T> struct less_equal <T ,::nbl::hlsl::enable_if_t<(concepts::Vectorial<T>),void> >{ using type_t = T; vector<bool, vector_traits<T>::Dimension> operator()(const in T lhs, const in T rhs) { return lhs <= rhs; }}; // ------------------------------------------------------------- COMPOUND ASSIGNMENT OPERATORS -------------------------------------------------------------------- #line 234 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/functional.hlsl" template<typename T> struct plus_assign { using type_t = T; using base_t = plus <type_t>; base_t baseOp; void operator()([[vk::ext_reference]] inout T lhs, const in T rhs) { lhs = baseOp(lhs, rhs); } const static T identity = base_t::identity; }; template<typename T> struct minus_assign { using type_t = T; using base_t = minus <type_t>; base_t baseOp; void operator()([[vk::ext_reference]] inout T lhs, const in T rhs) { lhs = baseOp(lhs, rhs); } const static T identity = base_t::identity; }; template<typename T> struct multiplies_assign { using type_t = T; using base_t = multiplies <type_t>; base_t baseOp; void operator()([[vk::ext_reference]] inout T lhs, const in T rhs) { lhs = baseOp(lhs, rhs); } const static T identity = base_t::identity; }; template<typename T> struct divides_assign { using type_t = T; using base_t = divides <type_t>; base_t baseOp; void operator()([[vk::ext_reference]] inout T lhs, const in T rhs) { lhs = baseOp(lhs, rhs); } const static T identity = base_t::identity; }; // ---------------------------------------------------------------- MIN, MAX, TERNARY ------------------------------------------------------------------------- // Min, Max, and Ternary and Shift operators don't use ALIAS_STD because they don't exist in STD // TODO: implement as mix(rhs<lhs,lhs,rhs) (SPIR-V intrinsic from the extended set & glm on C++) template<typename T> struct minimum { using type_t = T; using scalar_t = typename scalar_type<T>::type; T operator()(const in T lhs, const in T rhs) { return rhs<lhs ? rhs:lhs; } const static T identity = numeric_limits<scalar_t>::max; // TODO: `all_components<T>` }; template<typename T> struct maximum { using type_t = T; using scalar_t = typename scalar_type<T>::type; T operator()(const in T lhs, const in T rhs) { return lhs<rhs ? rhs:lhs; } const static T identity = numeric_limits<scalar_t>::lowest; // TODO: `all_components<T>` }; template<typename T ,typename __requires=void > struct ternary_operator { using type_t = T; inline T operator()(const in bool condition, const in T lhs, const in T rhs) { return select<bool, T>(condition, lhs, rhs); } }; // ----------------------------------------------------------------- SHIFT OPERATORS -------------------------------------------------------------------- template<typename T ,typename __requires=void > struct left_shift_operator { using type_t = T; inline T operator()(const in T operand, const in T bits) { return operand << bits; } }; template<typename T> struct left_shift_operator<T ,::nbl::hlsl::enable_if_t<(concepts::IntVector<T>),void> > { using type_t = T; using scalar_t = scalar_type_t<T>; inline T operator()(const in T operand, const in T bits) { return operand << bits; } inline T operator()(const in T operand, const in scalar_t bits) { return operand << bits; } }; template<typename T> struct left_shift_operator<T ,::nbl::hlsl::enable_if_t<(!concepts::IntVector<T> && concepts::IntegralLikeVectorial<T>),void> > { using type_t = T; using scalar_t = typename vector_traits<T>::scalar_type; inline T operator()(const in T operand, const in T bits) { array_get<T, scalar_t> getter; array_set<T, scalar_t> setter; const static uint16_t extent = uint16_t(extent_v<T>); left_shift_operator<scalar_t> leftShift; T shifted; [[unroll]] for (uint16_t i = 0; i < extent; i++) { setter(shifted, i, leftShift(getter(operand, i), getter(bits, i))); } return shifted; } inline T operator()(const in T operand, const in scalar_t bits) { array_get<T, scalar_t> getter; array_set<T, scalar_t> setter; const static uint16_t extent = uint16_t(extent_v<T>); left_shift_operator<scalar_t> leftShift; T shifted; [[unroll]] for (uint16_t i = 0; i < extent; i++) { setter(shifted, i, leftShift(getter(operand, i), bits)); } return shifted; } inline T operator()(const in T operand, const in vector<uint16_t, vector_traits<T>::Dimension> bits) { array_get<T, scalar_t> getter; array_set<T, scalar_t> setter; const static uint16_t extent = uint16_t(extent_v<T>); left_shift_operator<scalar_t> leftShift; T shifted; [[unroll]] for (uint16_t i = 0; i < extent; i++) { setter(shifted, i, leftShift(getter(operand, i), bits[i])); } return shifted; } inline T operator()(const in T operand, const in uint16_t bits) { array_get<T, scalar_t> getter; array_set<T, scalar_t> setter; const static uint16_t extent = uint16_t(extent_v<T>); left_shift_operator<scalar_t> leftShift; T shifted; [[unroll]] for (uint16_t i = 0; i < extent; i++) { setter(shifted, i, leftShift(getter(operand, i), bits)); } return shifted; } }; template<typename T ,typename __requires=void > struct arithmetic_right_shift_operator { using type_t = T; inline T operator()(const in T operand, const in T bits) { return operand >> bits; } }; template<typename T> struct arithmetic_right_shift_operator<T ,::nbl::hlsl::enable_if_t<(concepts::IntVector<T>),void> > { using type_t = T; using scalar_t = scalar_type_t<T>; inline T operator()(const in T operand, const in T bits) { return operand >> bits; } inline T operator()(const in T operand, const in scalar_t bits) { return operand >> bits; } }; template<typename T> struct arithmetic_right_shift_operator<T ,::nbl::hlsl::enable_if_t<(!concepts::IntVector<T>&& concepts::IntegralLikeVectorial<T>),void> > { using type_t = T; using scalar_t = typename vector_traits<T>::scalar_type; inline T operator()(const in T operand, const in T bits) { array_get<T, scalar_t> getter; array_set<T, scalar_t> setter; const static uint16_t extent = uint16_t(extent_v<T>); arithmetic_right_shift_operator<scalar_t> rightShift; T shifted; [[unroll]] for (uint16_t i = 0; i < extent; i++) { setter(shifted, i, rightShift(getter(operand, i), getter(bits, i))); } return shifted; } inline T operator()(const in T operand, const in scalar_t bits) { array_get<T, scalar_t> getter; array_set<T, scalar_t> setter; const static uint16_t extent = uint16_t(extent_v<T>); arithmetic_right_shift_operator<scalar_t> rightShift; T shifted; [[unroll]] for (uint16_t i = 0; i < extent; i++) { setter(shifted, i, rightShift(getter(operand, i), bits)); } return shifted; } inline T operator()(const in T operand, const in vector<uint16_t, vector_traits<T>::Dimension> bits) { array_get<T, scalar_t> getter; array_set<T, scalar_t> setter; const static uint16_t extent = uint16_t(extent_v<T>); arithmetic_right_shift_operator<scalar_t> rightShift; T shifted; [[unroll]] for (uint16_t i = 0; i < extent; i++) { setter(shifted, i, rightShift(getter(operand, i), bits[i])); } return shifted; } inline T operator()(const in T operand, const in uint16_t bits) { array_get<T, scalar_t> getter; array_set<T, scalar_t> setter; const static uint16_t extent = uint16_t(extent_v<T>); arithmetic_right_shift_operator<scalar_t> rightShift; T shifted; [[unroll]] for (uint16_t i = 0; i < extent; i++) { setter(shifted, i, rightShift(getter(operand, i), bits)); } return shifted; } }; // Left unimplemented for vectorial types by default template<typename T ,typename __requires=void > struct logical_right_shift_operator { using type_t = T; using unsigned_type_t = make_unsigned_t<T>; inline T operator()(const in T operand, const in T bits) { arithmetic_right_shift_operator<unsigned_type_t> arithmeticRightShift; return _static_cast<T>(arithmeticRightShift(_static_cast<unsigned_type_t>(operand), _static_cast<unsigned_type_t>(bits))); } }; } //namespace nbl } //namespace hlsl #line 11 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/complex.hlsl" using namespace nbl::hlsl; // -------------------------------------- CPP VERSION ------------------------------------ #line 50 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/complex.hlsl" namespace nbl { namespace hlsl { // TODO: make this BDA compatible (no unspecialized templates yet) template<typename Scalar> struct complex_t { Scalar m_real; Scalar m_imag; // ------------------------- Constructors --------------------------------------- static complex_t create(const in Scalar real, const in Scalar imag) { complex_t retVal = { real, imag }; return retVal; } // ------------------------- Member functions ------------------------------- Scalar real() { return m_real; } void real(const in Scalar value) { m_real = value; } Scalar imag() { return m_imag; } void imag(const in Scalar value) { m_imag = value; } // ------------------------- Arithmetic operators ------------------------------- complex_t operator+(const in complex_t rhs) { complex_t result; result.m_real = m_real + rhs.m_real; result.m_imag = m_imag + rhs.m_imag; return result; } complex_t operator-(const in complex_t rhs) { complex_t result; result.m_real = m_real - rhs.m_real; result.m_imag = m_imag - rhs.m_imag; return result; } complex_t operator*(const in complex_t rhs) { complex_t result; result.m_real = m_real * rhs.m_real - m_imag * rhs.m_imag; result.m_imag = m_real * rhs.m_imag + m_imag * rhs.m_real; return result; } // multiply by scalar complex_t operator*(const in Scalar scalar) { complex_t result; result.m_real = m_real * scalar; result.m_imag = m_imag * scalar; return result; } // Divide by scalar complex_t operator/(const in Scalar scalar) { complex_t result; result.m_real = m_real / scalar; result.m_imag = m_imag / scalar; return result; } complex_t operator/(const in complex_t rhs) { complex_t result; Scalar denominator = rhs.m_real * rhs.m_real + rhs.m_imag * rhs.m_imag; result.m_real = (m_real * rhs.m_real + m_imag * rhs.m_imag) / denominator; result.m_imag = (m_imag * rhs.m_real - m_real * rhs.m_imag) / denominator; return result; } // ----------------- Relational operators ----------------------------- bool operator==(const in complex_t rhs) { return m_real == rhs.m_real && m_imag == rhs.m_imag; } bool operator!=(const complex_t rhs) { return m_real != rhs.m_real || m_imag != rhs.m_imag; } }; // ---------------------- STD arithmetic operators ------------------------ // Specializations of the structs found in functional.hlsl // Could X-Macro, left as-is for readability // These all have to be specialized because of the identity that can't be initialized inside the struct definition, // and the latter (mul, div) have two overloads for operator() template<typename Scalar> struct plus< complex_t<Scalar> > { using type_t = complex_t<Scalar>; complex_t<Scalar> operator()(const in complex_t<Scalar> lhs, const in complex_t<Scalar> rhs) { return lhs + rhs; } const static complex_t<Scalar> identity; }; template<typename Scalar> struct minus< complex_t<Scalar> > { using type_t = complex_t<Scalar>; complex_t<Scalar> operator()(const in complex_t<Scalar> lhs, const in complex_t<Scalar> rhs) { return lhs - rhs; } const static complex_t<Scalar> identity; }; template<typename Scalar> struct multiplies< complex_t<Scalar> > { using type_t = complex_t<Scalar>; complex_t<Scalar> operator()(const in complex_t<Scalar> lhs, const in complex_t<Scalar> rhs) { return lhs * rhs; } complex_t<Scalar> operator()(const in complex_t<Scalar> lhs, const in Scalar rhs) { return lhs * rhs; } const static complex_t<Scalar> identity; }; template<typename Scalar> struct divides< complex_t<Scalar> > { using type_t = complex_t<Scalar>; complex_t<Scalar> operator()(const in complex_t<Scalar> lhs, const in complex_t<Scalar> rhs) { return lhs / rhs; } complex_t<Scalar> operator()(const in complex_t<Scalar> lhs, const in Scalar rhs) { return lhs / rhs; } const static complex_t<Scalar> identity; }; // Out of line generic initialization of static member data not yet supported so we X-Macro identities for Scalar types we want to support // (left X-Macro here since it's pretty readable) #line 243 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/complex.hlsl" template<> const static complex_t< float16_t > plus< complex_t< float16_t > >::identity = { promote< float16_t , uint32_t>(0), promote< float16_t , uint32_t>(0)}; template<> const static complex_t< float16_t > minus< complex_t< float16_t > >::identity = { promote< float16_t , uint32_t>(0), promote< float16_t , uint32_t>(0)}; template<> const static complex_t< float16_t > multiplies< complex_t< float16_t > >::identity = { promote< float16_t , uint32_t>(1), promote< float16_t , uint32_t>(0)}; template<> const static complex_t< float16_t > divides< complex_t< float16_t > >::identity = { promote< float16_t , uint32_t>(1), promote< float16_t , uint32_t>(0)}; template<> const static complex_t< float16_t2 > plus< complex_t< float16_t2 > >::identity = { promote< float16_t2 , uint32_t>(0), promote< float16_t2 , uint32_t>(0)}; template<> const static complex_t< float16_t2 > minus< complex_t< float16_t2 > >::identity = { promote< float16_t2 , uint32_t>(0), promote< float16_t2 , uint32_t>(0)}; template<> const static complex_t< float16_t2 > multiplies< complex_t< float16_t2 > >::identity = { promote< float16_t2 , uint32_t>(1), promote< float16_t2 , uint32_t>(0)}; template<> const static complex_t< float16_t2 > divides< complex_t< float16_t2 > >::identity = { promote< float16_t2 , uint32_t>(1), promote< float16_t2 , uint32_t>(0)}; template<> const static complex_t< float16_t3 > plus< complex_t< float16_t3 > >::identity = { promote< float16_t3 , uint32_t>(0), promote< float16_t3 , uint32_t>(0)}; template<> const static complex_t< float16_t3 > minus< complex_t< float16_t3 > >::identity = { promote< float16_t3 , uint32_t>(0), promote< float16_t3 , uint32_t>(0)}; template<> const static complex_t< float16_t3 > multiplies< complex_t< float16_t3 > >::identity = { promote< float16_t3 , uint32_t>(1), promote< float16_t3 , uint32_t>(0)}; template<> const static complex_t< float16_t3 > divides< complex_t< float16_t3 > >::identity = { promote< float16_t3 , uint32_t>(1), promote< float16_t3 , uint32_t>(0)}; template<> const static complex_t< float16_t4 > plus< complex_t< float16_t4 > >::identity = { promote< float16_t4 , uint32_t>(0), promote< float16_t4 , uint32_t>(0)}; template<> const static complex_t< float16_t4 > minus< complex_t< float16_t4 > >::identity = { promote< float16_t4 , uint32_t>(0), promote< float16_t4 , uint32_t>(0)}; template<> const static complex_t< float16_t4 > multiplies< complex_t< float16_t4 > >::identity = { promote< float16_t4 , uint32_t>(1), promote< float16_t4 , uint32_t>(0)}; template<> const static complex_t< float16_t4 > divides< complex_t< float16_t4 > >::identity = { promote< float16_t4 , uint32_t>(1), promote< float16_t4 , uint32_t>(0)}; template<> const static complex_t< float32_t > plus< complex_t< float32_t > >::identity = { promote< float32_t , uint32_t>(0), promote< float32_t , uint32_t>(0)}; template<> const static complex_t< float32_t > minus< complex_t< float32_t > >::identity = { promote< float32_t , uint32_t>(0), promote< float32_t , uint32_t>(0)}; template<> const static complex_t< float32_t > multiplies< complex_t< float32_t > >::identity = { promote< float32_t , uint32_t>(1), promote< float32_t , uint32_t>(0)}; template<> const static complex_t< float32_t > divides< complex_t< float32_t > >::identity = { promote< float32_t , uint32_t>(1), promote< float32_t , uint32_t>(0)}; template<> const static complex_t< float32_t2 > plus< complex_t< float32_t2 > >::identity = { promote< float32_t2 , uint32_t>(0), promote< float32_t2 , uint32_t>(0)}; template<> const static complex_t< float32_t2 > minus< complex_t< float32_t2 > >::identity = { promote< float32_t2 , uint32_t>(0), promote< float32_t2 , uint32_t>(0)}; template<> const static complex_t< float32_t2 > multiplies< complex_t< float32_t2 > >::identity = { promote< float32_t2 , uint32_t>(1), promote< float32_t2 , uint32_t>(0)}; template<> const static complex_t< float32_t2 > divides< complex_t< float32_t2 > >::identity = { promote< float32_t2 , uint32_t>(1), promote< float32_t2 , uint32_t>(0)}; template<> const static complex_t< float32_t3 > plus< complex_t< float32_t3 > >::identity = { promote< float32_t3 , uint32_t>(0), promote< float32_t3 , uint32_t>(0)}; template<> const static complex_t< float32_t3 > minus< complex_t< float32_t3 > >::identity = { promote< float32_t3 , uint32_t>(0), promote< float32_t3 , uint32_t>(0)}; template<> const static complex_t< float32_t3 > multiplies< complex_t< float32_t3 > >::identity = { promote< float32_t3 , uint32_t>(1), promote< float32_t3 , uint32_t>(0)}; template<> const static complex_t< float32_t3 > divides< complex_t< float32_t3 > >::identity = { promote< float32_t3 , uint32_t>(1), promote< float32_t3 , uint32_t>(0)}; template<> const static complex_t< float32_t4 > plus< complex_t< float32_t4 > >::identity = { promote< float32_t4 , uint32_t>(0), promote< float32_t4 , uint32_t>(0)}; template<> const static complex_t< float32_t4 > minus< complex_t< float32_t4 > >::identity = { promote< float32_t4 , uint32_t>(0), promote< float32_t4 , uint32_t>(0)}; template<> const static complex_t< float32_t4 > multiplies< complex_t< float32_t4 > >::identity = { promote< float32_t4 , uint32_t>(1), promote< float32_t4 , uint32_t>(0)}; template<> const static complex_t< float32_t4 > divides< complex_t< float32_t4 > >::identity = { promote< float32_t4 , uint32_t>(1), promote< float32_t4 , uint32_t>(0)}; template<> const static complex_t< float64_t > plus< complex_t< float64_t > >::identity = { promote< float64_t , uint32_t>(0), promote< float64_t , uint32_t>(0)}; template<> const static complex_t< float64_t > minus< complex_t< float64_t > >::identity = { promote< float64_t , uint32_t>(0), promote< float64_t , uint32_t>(0)}; template<> const static complex_t< float64_t > multiplies< complex_t< float64_t > >::identity = { promote< float64_t , uint32_t>(1), promote< float64_t , uint32_t>(0)}; template<> const static complex_t< float64_t > divides< complex_t< float64_t > >::identity = { promote< float64_t , uint32_t>(1), promote< float64_t , uint32_t>(0)}; template<> const static complex_t< float64_t2 > plus< complex_t< float64_t2 > >::identity = { promote< float64_t2 , uint32_t>(0), promote< float64_t2 , uint32_t>(0)}; template<> const static complex_t< float64_t2 > minus< complex_t< float64_t2 > >::identity = { promote< float64_t2 , uint32_t>(0), promote< float64_t2 , uint32_t>(0)}; template<> const static complex_t< float64_t2 > multiplies< complex_t< float64_t2 > >::identity = { promote< float64_t2 , uint32_t>(1), promote< float64_t2 , uint32_t>(0)}; template<> const static complex_t< float64_t2 > divides< complex_t< float64_t2 > >::identity = { promote< float64_t2 , uint32_t>(1), promote< float64_t2 , uint32_t>(0)}; template<> const static complex_t< float64_t3 > plus< complex_t< float64_t3 > >::identity = { promote< float64_t3 , uint32_t>(0), promote< float64_t3 , uint32_t>(0)}; template<> const static complex_t< float64_t3 > minus< complex_t< float64_t3 > >::identity = { promote< float64_t3 , uint32_t>(0), promote< float64_t3 , uint32_t>(0)}; template<> const static complex_t< float64_t3 > multiplies< complex_t< float64_t3 > >::identity = { promote< float64_t3 , uint32_t>(1), promote< float64_t3 , uint32_t>(0)}; template<> const static complex_t< float64_t3 > divides< complex_t< float64_t3 > >::identity = { promote< float64_t3 , uint32_t>(1), promote< float64_t3 , uint32_t>(0)}; template<> const static complex_t< float64_t4 > plus< complex_t< float64_t4 > >::identity = { promote< float64_t4 , uint32_t>(0), promote< float64_t4 , uint32_t>(0)}; template<> const static complex_t< float64_t4 > minus< complex_t< float64_t4 > >::identity = { promote< float64_t4 , uint32_t>(0), promote< float64_t4 , uint32_t>(0)}; template<> const static complex_t< float64_t4 > multiplies< complex_t< float64_t4 > >::identity = { promote< float64_t4 , uint32_t>(1), promote< float64_t4 , uint32_t>(0)}; template<> const static complex_t< float64_t4 > divides< complex_t< float64_t4 > >::identity = { promote< float64_t4 , uint32_t>(1), promote< float64_t4 , uint32_t>(0)}; // --------------------------------- Compound assignment operators ------------------------------------------ // Specializations of the structs found in functional.hlsl // Could X-Macro these as well // Once again the identity forces us to template specialize instead of using the generic version implied by functional.hlsl template<typename Scalar> struct plus_assign< complex_t<Scalar> > { using type_t = complex_t<Scalar>; using base_t = plus<type_t>; base_t baseOp; void operator()([[vk::ext_reference]] inout complex_t<Scalar> lhs, const in complex_t<Scalar> rhs) { lhs = baseOp(lhs, rhs); } const static complex_t<Scalar> identity; }; template<typename Scalar> struct minus_assign< complex_t<Scalar> > { using type_t = complex_t<Scalar>; using base_t = minus<type_t>; base_t baseOp; void operator()([[vk::ext_reference]] inout complex_t<Scalar> lhs, const in complex_t<Scalar> rhs) { lhs = baseOp(lhs, rhs); } const static complex_t<Scalar> identity; }; template<typename Scalar> struct multiplies_assign< complex_t<Scalar> > { using type_t = complex_t<Scalar>; using base_t = multiplies<type_t>; base_t baseOp; void operator()([[vk::ext_reference]] inout complex_t<Scalar> lhs, const in complex_t<Scalar> rhs) { lhs = baseOp(lhs, rhs); } void operator()([[vk::ext_reference]] inout complex_t<Scalar> lhs, const in Scalar rhs) { lhs = baseOp(lhs, rhs); } const static complex_t<Scalar> identity; }; template<typename Scalar> struct divides_assign< complex_t<Scalar> > { using type_t = complex_t<Scalar>; using base_t = divides<type_t>; base_t baseOp; void operator()([[vk::ext_reference]] inout complex_t<Scalar> lhs, const in complex_t<Scalar> rhs) { lhs = baseOp(lhs, rhs); } void operator()([[vk::ext_reference]] inout complex_t<Scalar> lhs, const in Scalar rhs) { lhs = baseOp(lhs, rhs); } const static complex_t<Scalar> identity; }; // Once again have to do some ugly out of line initialization for each Scalar type we want to support #line 343 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/complex.hlsl" template<> const static complex_t< float16_t > plus_assign< complex_t< float16_t > >::identity = plus < complex_t< float16_t > >::identity; template<> const static complex_t< float16_t > minus_assign< complex_t< float16_t > >::identity = minus < complex_t< float16_t > >::identity; template<> const static complex_t< float16_t > multiplies_assign< complex_t< float16_t > >::identity = multiplies < complex_t< float16_t > >::identity; template<> const static complex_t< float16_t > divides_assign< complex_t< float16_t > >::identity = divides < complex_t< float16_t > >::identity; template<> const static complex_t< float16_t2 > plus_assign< complex_t< float16_t2 > >::identity = plus < complex_t< float16_t2 > >::identity; template<> const static complex_t< float16_t2 > minus_assign< complex_t< float16_t2 > >::identity = minus < complex_t< float16_t2 > >::identity; template<> const static complex_t< float16_t2 > multiplies_assign< complex_t< float16_t2 > >::identity = multiplies < complex_t< float16_t2 > >::identity; template<> const static complex_t< float16_t2 > divides_assign< complex_t< float16_t2 > >::identity = divides < complex_t< float16_t2 > >::identity; template<> const static complex_t< float16_t3 > plus_assign< complex_t< float16_t3 > >::identity = plus < complex_t< float16_t3 > >::identity; template<> const static complex_t< float16_t3 > minus_assign< complex_t< float16_t3 > >::identity = minus < complex_t< float16_t3 > >::identity; template<> const static complex_t< float16_t3 > multiplies_assign< complex_t< float16_t3 > >::identity = multiplies < complex_t< float16_t3 > >::identity; template<> const static complex_t< float16_t3 > divides_assign< complex_t< float16_t3 > >::identity = divides < complex_t< float16_t3 > >::identity; template<> const static complex_t< float16_t4 > plus_assign< complex_t< float16_t4 > >::identity = plus < complex_t< float16_t4 > >::identity; template<> const static complex_t< float16_t4 > minus_assign< complex_t< float16_t4 > >::identity = minus < complex_t< float16_t4 > >::identity; template<> const static complex_t< float16_t4 > multiplies_assign< complex_t< float16_t4 > >::identity = multiplies < complex_t< float16_t4 > >::identity; template<> const static complex_t< float16_t4 > divides_assign< complex_t< float16_t4 > >::identity = divides < complex_t< float16_t4 > >::identity; template<> const static complex_t< float32_t > plus_assign< complex_t< float32_t > >::identity = plus < complex_t< float32_t > >::identity; template<> const static complex_t< float32_t > minus_assign< complex_t< float32_t > >::identity = minus < complex_t< float32_t > >::identity; template<> const static complex_t< float32_t > multiplies_assign< complex_t< float32_t > >::identity = multiplies < complex_t< float32_t > >::identity; template<> const static complex_t< float32_t > divides_assign< complex_t< float32_t > >::identity = divides < complex_t< float32_t > >::identity; template<> const static complex_t< float32_t2 > plus_assign< complex_t< float32_t2 > >::identity = plus < complex_t< float32_t2 > >::identity; template<> const static complex_t< float32_t2 > minus_assign< complex_t< float32_t2 > >::identity = minus < complex_t< float32_t2 > >::identity; template<> const static complex_t< float32_t2 > multiplies_assign< complex_t< float32_t2 > >::identity = multiplies < complex_t< float32_t2 > >::identity; template<> const static complex_t< float32_t2 > divides_assign< complex_t< float32_t2 > >::identity = divides < complex_t< float32_t2 > >::identity; template<> const static complex_t< float32_t3 > plus_assign< complex_t< float32_t3 > >::identity = plus < complex_t< float32_t3 > >::identity; template<> const static complex_t< float32_t3 > minus_assign< complex_t< float32_t3 > >::identity = minus < complex_t< float32_t3 > >::identity; template<> const static complex_t< float32_t3 > multiplies_assign< complex_t< float32_t3 > >::identity = multiplies < complex_t< float32_t3 > >::identity; template<> const static complex_t< float32_t3 > divides_assign< complex_t< float32_t3 > >::identity = divides < complex_t< float32_t3 > >::identity; template<> const static complex_t< float32_t4 > plus_assign< complex_t< float32_t4 > >::identity = plus < complex_t< float32_t4 > >::identity; template<> const static complex_t< float32_t4 > minus_assign< complex_t< float32_t4 > >::identity = minus < complex_t< float32_t4 > >::identity; template<> const static complex_t< float32_t4 > multiplies_assign< complex_t< float32_t4 > >::identity = multiplies < complex_t< float32_t4 > >::identity; template<> const static complex_t< float32_t4 > divides_assign< complex_t< float32_t4 > >::identity = divides < complex_t< float32_t4 > >::identity; template<> const static complex_t< float64_t > plus_assign< complex_t< float64_t > >::identity = plus < complex_t< float64_t > >::identity; template<> const static complex_t< float64_t > minus_assign< complex_t< float64_t > >::identity = minus < complex_t< float64_t > >::identity; template<> const static complex_t< float64_t > multiplies_assign< complex_t< float64_t > >::identity = multiplies < complex_t< float64_t > >::identity; template<> const static complex_t< float64_t > divides_assign< complex_t< float64_t > >::identity = divides < complex_t< float64_t > >::identity; template<> const static complex_t< float64_t2 > plus_assign< complex_t< float64_t2 > >::identity = plus < complex_t< float64_t2 > >::identity; template<> const static complex_t< float64_t2 > minus_assign< complex_t< float64_t2 > >::identity = minus < complex_t< float64_t2 > >::identity; template<> const static complex_t< float64_t2 > multiplies_assign< complex_t< float64_t2 > >::identity = multiplies < complex_t< float64_t2 > >::identity; template<> const static complex_t< float64_t2 > divides_assign< complex_t< float64_t2 > >::identity = divides < complex_t< float64_t2 > >::identity; template<> const static complex_t< float64_t3 > plus_assign< complex_t< float64_t3 > >::identity = plus < complex_t< float64_t3 > >::identity; template<> const static complex_t< float64_t3 > minus_assign< complex_t< float64_t3 > >::identity = minus < complex_t< float64_t3 > >::identity; template<> const static complex_t< float64_t3 > multiplies_assign< complex_t< float64_t3 > >::identity = multiplies < complex_t< float64_t3 > >::identity; template<> const static complex_t< float64_t3 > divides_assign< complex_t< float64_t3 > >::identity = divides < complex_t< float64_t3 > >::identity; template<> const static complex_t< float64_t4 > plus_assign< complex_t< float64_t4 > >::identity = plus < complex_t< float64_t4 > >::identity; template<> const static complex_t< float64_t4 > minus_assign< complex_t< float64_t4 > >::identity = minus < complex_t< float64_t4 > >::identity; template<> const static complex_t< float64_t4 > multiplies_assign< complex_t< float64_t4 > >::identity = multiplies < complex_t< float64_t4 > >::identity; template<> const static complex_t< float64_t4 > divides_assign< complex_t< float64_t4 > >::identity = divides < complex_t< float64_t4 > >::identity; // -------------------------------- Non-member functions -------------------------------------- template<typename Scalar> Scalar real(const in complex_t<Scalar> c) { return c.m_real; } template<typename Scalar> Scalar imag(const in complex_t<Scalar> c) { return c.m_imag; } template<typename Scalar> Scalar norm(const in complex_t<Scalar> c) { return c.m_real * c.m_real + c.m_imag * c.m_imag; } template<typename Scalar> Scalar abs(const in complex_t<Scalar> c) { return sqrt(norm(c)); } template<typename Scalar> Scalar arg(const in complex_t<Scalar> c) { return atan2(c.m_imag, c.m_real); } template<typename Scalar> complex_t<Scalar> conj(const in complex_t<Scalar> c) { complex_t<Scalar> retVal = { c.m_real, -c.m_imag }; return retVal; } template<typename Scalar> complex_t<Scalar> proj(const in complex_t<Scalar> c) { Scalar den = norm(c) + Scalar(1.0); complex_t<Scalar> retVal = { (Scalar(2.0) * c.m_real) / den , (Scalar(2.0) * c.m_imag) / den}; return retVal; } template<typename Scalar> complex_t<Scalar> polar(const in Scalar r, const in Scalar theta) { complex_t<Scalar> retVal = {r * cos(theta), r * sin(theta)}; return retVal; } // --------------------------------------------- Some more functions that come in handy -------------------------------------- // Fast mul by i template<typename Scalar> complex_t<Scalar> rotateLeft(const in complex_t<Scalar> value) { complex_t<Scalar> retVal = { -value.imag(), value.real() }; return retVal; } // Fast mul by -i template<typename Scalar> complex_t<Scalar> rotateRight(const in complex_t<Scalar> value) { complex_t<Scalar> retVal = { value.imag(), -value.real() }; return retVal; } } } // due to lack of alignof and typeid in DXC, need C++03 style tricks namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<complex_t<float16_t> > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<complex_t<float16_t> > : integral_constant<uint32_t,::nbl::hlsl::alignment_of_v<float16_t> > {}; template<> struct alignment_of<const complex_t<float16_t> > : integral_constant<uint32_t,::nbl::hlsl::alignment_of_v<float16_t> > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<complex_t<float16_t> >::type> : integral_constant<uint32_t,::nbl::hlsl::alignment_of_v<float16_t> > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const complex_t<float16_t> >::type> : integral_constant<uint32_t,::nbl::hlsl::alignment_of_v<float16_t> > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<complex_t<float16_t2> > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<complex_t<float16_t2> > : integral_constant<uint32_t,::nbl::hlsl::alignment_of_v<float16_t2> > {}; template<> struct alignment_of<const complex_t<float16_t2> > : integral_constant<uint32_t,::nbl::hlsl::alignment_of_v<float16_t2> > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<complex_t<float16_t2> >::type> : integral_constant<uint32_t,::nbl::hlsl::alignment_of_v<float16_t2> > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const complex_t<float16_t2> >::type> : integral_constant<uint32_t,::nbl::hlsl::alignment_of_v<float16_t2> > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<complex_t<float16_t3> > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<complex_t<float16_t3> > : integral_constant<uint32_t,::nbl::hlsl::alignment_of_v<float16_t3> > {}; template<> struct alignment_of<const complex_t<float16_t3> > : integral_constant<uint32_t,::nbl::hlsl::alignment_of_v<float16_t3> > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<complex_t<float16_t3> >::type> : integral_constant<uint32_t,::nbl::hlsl::alignment_of_v<float16_t3> > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const complex_t<float16_t3> >::type> : integral_constant<uint32_t,::nbl::hlsl::alignment_of_v<float16_t3> > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<complex_t<float16_t4> > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<complex_t<float16_t4> > : integral_constant<uint32_t,::nbl::hlsl::alignment_of_v<float16_t4> > {}; template<> struct alignment_of<const complex_t<float16_t4> > : integral_constant<uint32_t,::nbl::hlsl::alignment_of_v<float16_t4> > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<complex_t<float16_t4> >::type> : integral_constant<uint32_t,::nbl::hlsl::alignment_of_v<float16_t4> > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const complex_t<float16_t4> >::type> : integral_constant<uint32_t,::nbl::hlsl::alignment_of_v<float16_t4> > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<complex_t<float32_t> > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<complex_t<float32_t> > : integral_constant<uint32_t,::nbl::hlsl::alignment_of_v<float32_t> > {}; template<> struct alignment_of<const complex_t<float32_t> > : integral_constant<uint32_t,::nbl::hlsl::alignment_of_v<float32_t> > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<complex_t<float32_t> >::type> : integral_constant<uint32_t,::nbl::hlsl::alignment_of_v<float32_t> > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const complex_t<float32_t> >::type> : integral_constant<uint32_t,::nbl::hlsl::alignment_of_v<float32_t> > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<complex_t<float32_t2> > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<complex_t<float32_t2> > : integral_constant<uint32_t,::nbl::hlsl::alignment_of_v<float32_t2> > {}; template<> struct alignment_of<const complex_t<float32_t2> > : integral_constant<uint32_t,::nbl::hlsl::alignment_of_v<float32_t2> > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<complex_t<float32_t2> >::type> : integral_constant<uint32_t,::nbl::hlsl::alignment_of_v<float32_t2> > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const complex_t<float32_t2> >::type> : integral_constant<uint32_t,::nbl::hlsl::alignment_of_v<float32_t2> > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<complex_t<float32_t3> > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<complex_t<float32_t3> > : integral_constant<uint32_t,::nbl::hlsl::alignment_of_v<float32_t3> > {}; template<> struct alignment_of<const complex_t<float32_t3> > : integral_constant<uint32_t,::nbl::hlsl::alignment_of_v<float32_t3> > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<complex_t<float32_t3> >::type> : integral_constant<uint32_t,::nbl::hlsl::alignment_of_v<float32_t3> > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const complex_t<float32_t3> >::type> : integral_constant<uint32_t,::nbl::hlsl::alignment_of_v<float32_t3> > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<complex_t<float32_t4> > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<complex_t<float32_t4> > : integral_constant<uint32_t,::nbl::hlsl::alignment_of_v<float32_t4> > {}; template<> struct alignment_of<const complex_t<float32_t4> > : integral_constant<uint32_t,::nbl::hlsl::alignment_of_v<float32_t4> > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<complex_t<float32_t4> >::type> : integral_constant<uint32_t,::nbl::hlsl::alignment_of_v<float32_t4> > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const complex_t<float32_t4> >::type> : integral_constant<uint32_t,::nbl::hlsl::alignment_of_v<float32_t4> > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<complex_t<float64_t> > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<complex_t<float64_t> > : integral_constant<uint32_t,::nbl::hlsl::alignment_of_v<float64_t> > {}; template<> struct alignment_of<const complex_t<float64_t> > : integral_constant<uint32_t,::nbl::hlsl::alignment_of_v<float64_t> > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<complex_t<float64_t> >::type> : integral_constant<uint32_t,::nbl::hlsl::alignment_of_v<float64_t> > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const complex_t<float64_t> >::type> : integral_constant<uint32_t,::nbl::hlsl::alignment_of_v<float64_t> > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<complex_t<float64_t2> > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<complex_t<float64_t2> > : integral_constant<uint32_t,::nbl::hlsl::alignment_of_v<float64_t2> > {}; template<> struct alignment_of<const complex_t<float64_t2> > : integral_constant<uint32_t,::nbl::hlsl::alignment_of_v<float64_t2> > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<complex_t<float64_t2> >::type> : integral_constant<uint32_t,::nbl::hlsl::alignment_of_v<float64_t2> > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const complex_t<float64_t2> >::type> : integral_constant<uint32_t,::nbl::hlsl::alignment_of_v<float64_t2> > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<complex_t<float64_t3> > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<complex_t<float64_t3> > : integral_constant<uint32_t,::nbl::hlsl::alignment_of_v<float64_t3> > {}; template<> struct alignment_of<const complex_t<float64_t3> > : integral_constant<uint32_t,::nbl::hlsl::alignment_of_v<float64_t3> > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<complex_t<float64_t3> >::type> : integral_constant<uint32_t,::nbl::hlsl::alignment_of_v<float64_t3> > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const complex_t<float64_t3> >::type> : integral_constant<uint32_t,::nbl::hlsl::alignment_of_v<float64_t3> > {}; }} namespace nbl { namespace hlsl { namespace impl { template<> struct typeid_t<complex_t<float64_t4> > : integral_constant<uint32_t,__COUNTER__> {}; } template<> struct alignment_of<complex_t<float64_t4> > : integral_constant<uint32_t,::nbl::hlsl::alignment_of_v<float64_t4> > {}; template<> struct alignment_of<const complex_t<float64_t4> > : integral_constant<uint32_t,::nbl::hlsl::alignment_of_v<float64_t4> > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<complex_t<float64_t4> >::type> : integral_constant<uint32_t,::nbl::hlsl::alignment_of_v<float64_t4> > {}; template<> struct alignment_of<typename impl::add_lvalue_reference<const complex_t<float64_t4> >::type> : integral_constant<uint32_t,::nbl::hlsl::alignment_of_v<float64_t4> > {}; }} // -------------------------------------- END HLSL VERSION --------------------------------------- #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts.hlsl" // Copyright (C) 2023-2024 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/type_traits.hlsl" // Copyright (C) 2022 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 7 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/math/intutil.hlsl" namespace nbl { namespace hlsl { template<typename Integer ,::nbl::hlsl::enable_if_t<(is_integral_v<Integer>),bool> = true> inline bool isNPoT(Integer value) { return value & (value - Integer(1)); } template<typename Integer ,::nbl::hlsl::enable_if_t<(is_integral_v<Integer>),bool> = true> inline bool isPoT(Integer value) { return !isNPoT<Integer>(value); } template<typename Integer ,::nbl::hlsl::enable_if_t<(is_integral_v<Integer>),bool> = true> inline Integer roundUpToPoT(Integer value) { return Integer(0x1u) << Integer(1 + hlsl::findMSB<Integer>(value - Integer(1))); // this wont result in constexpr because findMSB is not one } template<typename Integer ,::nbl::hlsl::enable_if_t<(is_integral_v<Integer>),bool> = true> inline Integer roundDownToPoT(Integer value) { return Integer(0x1u) << hlsl::findMSB<Integer>(value); } template<typename Integer ,::nbl::hlsl::enable_if_t<(is_integral_v<Integer>),bool> = true> inline Integer roundUp(Integer value, Integer multiple) { Integer tmp = (value + multiple - 1u) / multiple; return tmp * multiple; } template<typename Integer ,::nbl::hlsl::enable_if_t<(is_integral_v<Integer>),bool> = true> inline Integer align(Integer alignment, Integer size, [[vk::ext_reference]] inout Integer address, [[vk::ext_reference]] inout Integer space) { Integer nextAlignedAddr = roundUp<Integer>(address, alignment); Integer spaceDecrement = nextAlignedAddr - address; if (spaceDecrement > space) return 0u; Integer newSpace = space - spaceDecrement; if (size > newSpace) return 0u; space = newSpace; return address = nextAlignedAddr; } // ------------------------------------- CPP ONLY ---------------------------------------------------------- #line 82 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/math/intutil.hlsl" } // end namespace hlsl } // end namespace nbl #line 10 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/fft/common.hlsl" namespace nbl { namespace hlsl { namespace fft { template <uint16_t N ,::nbl::hlsl::enable_if_t<(N > 0 && N <= 4),bool> = true> /** * @brief Returns the size of the full FFT computed, in terms of number of complex elements. If the signal is real, you MUST provide a valid value for `firstAxis` * * @tparam N Number of dimensions of the signal to perform FFT on. * * @param [in] dimensions Size of the signal. * @param [in] firstAxis Indicates which axis the FFT is performed on first. Only relevant for real-valued signals, in which case it must be less than N. N by default. */ inline vector<uint64_t, N> padDimensions(vector<uint32_t, N> dimensions, uint16_t firstAxis = N) { vector<uint32_t, N> newDimensions = dimensions; for (uint16_t i = 0u; i < N; i++) { newDimensions[i] = hlsl::roundUpToPoT(newDimensions[i]); } if (firstAxis < N) newDimensions[firstAxis] /= 2; return newDimensions; } template <uint16_t N ,::nbl::hlsl::enable_if_t<(N > 0 && N <= 4),bool> = true> /** * @brief Returns the size required by a buffer to hold the result of the FFT of a signal after a certain pass. * * @tparam N Number of dimensions of the signal to perform FFT on. * * @param [in] numChannels Number of channels of the signal. * @param [in] inputDimensions Size of the signal. * @param [in] passIx Which pass the size is being computed for. * @param [in] axisPassOrder Order of the axis in which the FFT is computed in. Default is xyzw. * @param [in] realFFT True if the signal is real. False by default. * @param [in] halfFloats True if using half-precision floats. False by default. */ inline uint64_t getOutputBufferSize( uint32_t numChannels, vector<uint32_t, N> inputDimensions, uint16_t passIx, vector<uint16_t, N> axisPassOrder = _static_cast<vector<uint16_t, N> >(uint16_t4(0, 1, 2, 3)), bool realFFT = false, bool halfFloats = false ) { const vector<uint32_t, N> paddedDimensions = padDimensions<N>(inputDimensions, realFFT ? axisPassOrder[0] : N); vector<bool, N> axesDone = promote<vector<bool, N>, bool>(false); for (uint16_t i = 0; i <= passIx; i++) axesDone[axisPassOrder[i]] = true; const vector<uint32_t, N> passOutputDimension = lerp(inputDimensions, paddedDimensions, axesDone); uint64_t numberOfComplexElements = uint64_t(numChannels); for (uint16_t i = 0; i < N; i++) numberOfComplexElements *= uint64_t(passOutputDimension[i]); return numberOfComplexElements * (halfFloats ? sizeof(complex_t<float16_t>) : sizeof(complex_t<float32_t>)); } template <uint16_t N ,::nbl::hlsl::enable_if_t<(N > 0 && N <= 4),bool> = true> /** * @brief Returns the size required by a buffer to hold the result of the FFT of a signal after a certain pass, when using the FFT to convolve it against a kernel. * * @tparam N Number of dimensions of the signal to perform FFT on. * * @param [in] numChannels Number of channels of the signal. * @param [in] inputDimensions Size of the signal. * @param [in] kernelDimensions Size of the kernel. * @param [in] passIx Which pass the size is being computed for. * @param [in] axisPassOrder Order of the axis in which the FFT is computed in. Default is xyzw. * @param [in] realFFT True if the signal is real. False by default. * @param [in] halfFloats True if using half-precision floats. False by default. */ inline uint64_t getOutputBufferSizeConvolution( uint32_t numChannels, vector<uint32_t, N> inputDimensions, vector<uint32_t, N> kernelDimensions, uint16_t passIx, vector<uint16_t, N> axisPassOrder = _static_cast<vector<uint16_t, N> >(uint16_t4(0, 1, 2, 3)), bool realFFT = false, bool halfFloats = false ) { const vector<uint32_t, N> paddedDimensions = padDimensions<N>(inputDimensions + kernelDimensions, realFFT ? axisPassOrder[0] : N); vector<bool, N> axesDone = promote<vector<bool, N>, bool>(false); for (uint16_t i = 0; i <= passIx; i++) axesDone[axisPassOrder[i]] = true; const vector<uint32_t, N> passOutputDimension = lerp(inputDimensions, paddedDimensions, axesDone); uint64_t numberOfComplexElements = uint64_t(numChannels); for (uint16_t i = 0; i < N; i++) numberOfComplexElements *= uint64_t(passOutputDimension[i]); return numberOfComplexElements * (halfFloats ? sizeof(complex_t<float16_t>) : sizeof(complex_t<float32_t>)); } // Computes the kth element in the group of N roots of unity // Notice 0 <= k < N/2, rotating counterclockwise in the forward (DIF) transform and clockwise in the inverse (DIT) template<bool inverse, typename Scalar> complex_t<Scalar> twiddle(uint32_t k, uint32_t halfN) { complex_t<Scalar> retVal; const Scalar kthRootAngleRadians = numbers::pi<Scalar> *Scalar(k) / Scalar(halfN); retVal.real(cos(kthRootAngleRadians)); if (!inverse) retVal.imag(sin(-kthRootAngleRadians)); else retVal.imag(sin(kthRootAngleRadians)); return retVal; } template<bool inverse, typename Scalar> struct DIX { static void radix2(complex_t<Scalar> twiddle, [[vk::ext_reference]] inout complex_t<Scalar> lo, [[vk::ext_reference]] inout complex_t<Scalar> hi) { plus_assign< complex_t<Scalar> > plusAss; //Decimation in time - inverse if (inverse) { complex_t<Scalar> wHi = twiddle * hi; hi = lo - wHi; plusAss(lo, wHi); } //Decimation in frequency - forward else { complex_t<Scalar> diff = lo - hi; plusAss(lo, hi); hi = twiddle * diff; } } }; template<typename Scalar> using DIT = DIX<true, Scalar>; template<typename Scalar> using DIF = DIX<false, Scalar>; // ------------------------------------------------- Utils --------------------------------------------------------- // // Util to unpack two values from the packed FFT X + iY - get outputs in the same input arguments, storing x to lo and y to hi template<typename Scalar> void unpack([[vk::ext_reference]] inout complex_t<Scalar> lo, [[vk::ext_reference]] inout complex_t<Scalar> hi) { complex_t<Scalar> x = (lo + conj(hi)) * Scalar(0.5); hi = rotateRight<Scalar>(lo - conj(hi)) * Scalar(0.5); lo = x; } } } } #line 8 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/workgroup/fft.hlsl" // ------------------------------- COMMON ----------------------------------------- namespace nbl { namespace hlsl { namespace workgroup { namespace fft { template<uint16_t _ElementsPerInvocationLog2, uint16_t _WorkgroupSizeLog2, typename _Scalar ,typename __requires=::nbl::hlsl::enable_if_t<(_ElementsPerInvocationLog2 > 0 && _WorkgroupSizeLog2 >= 5),void> > struct ConstevalParameters { using scalar_t = _Scalar; const static uint16_t ElementsPerInvocationLog2 = _ElementsPerInvocationLog2; const static uint16_t WorkgroupSizeLog2 = _WorkgroupSizeLog2; const static uint32_t TotalSize = uint32_t(1) << (ElementsPerInvocationLog2 + WorkgroupSizeLog2); const static uint16_t ElementsPerInvocation = uint16_t(1) << ElementsPerInvocationLog2; const static uint16_t WorkgroupSize = uint16_t(1) << WorkgroupSizeLog2; // Required size (in number of uint32_t elements) of the workgroup shared memory array needed for the FFT const static uint32_t SharedMemoryDWORDs = (sizeof(complex_t<scalar_t>) / sizeof(uint32_t)) << WorkgroupSizeLog2; }; struct OptimalFFTParameters { uint16_t elementsPerInvocationLog2 : 8; uint16_t workgroupSizeLog2 : 8; // Used to check if the parameters returned by `optimalFFTParameters` are valid bool areValid() { return elementsPerInvocationLog2 > 0 && workgroupSizeLog2 > 0; } }; /** * @brief Returns the best parameters (according to our metric) to run an FFT * * @param [in] maxWorkgroupSize The max number of threads that can be launched in a single workgroup * @param [in] inputArrayLength The length of the array to run an FFT on * @param [in] minSubgroupSize The smallest possible number of threads that can run in a single subgroup. 32 by default. */ inline OptimalFFTParameters optimalFFTParameters(uint32_t maxWorkgroupSize, uint32_t inputArrayLength, uint32_t minSubgroupSize) { const OptimalFFTParameters invalidParameters = { 0 , 0 }; if (minSubgroupSize < 4 || maxWorkgroupSize < minSubgroupSize || inputArrayLength <= minSubgroupSize) return invalidParameters; // Round inputArrayLength to PoT const uint32_t FFTLength = hlsl::roundUpToPoT(inputArrayLength); // Round maxWorkgroupSize down to PoT const uint32_t actualMaxWorkgroupSize = hlsl::roundDownToPoT(maxWorkgroupSize); // This is the logic found in hlsl::roundUpToPoT to get the log2 const uint16_t workgroupSizeLog2 = _static_cast<uint16_t>(1u + findMSB(_static_cast<uint32_t>(min(FFTLength / 2, actualMaxWorkgroupSize) - 1u))); // Parameters are valid if the workgroup size is at most half of the FFT Length and at least as big as the smallest subgroup that can be launched if ((FFTLength >> workgroupSizeLog2) <= 1 || minSubgroupSize > (1u << workgroupSizeLog2)) { return invalidParameters; } const uint16_t elementsPerInvocationLog2 = _static_cast<uint16_t>(findMSB(FFTLength >> workgroupSizeLog2)); const OptimalFFTParameters retVal = { elementsPerInvocationLog2, workgroupSizeLog2 }; return retVal; } namespace impl { // Given an `N`-bit number, leaves the `N - H` LSB alone and performs a circular bitshift right by `B` bits on the `H` MSB template<uint16_t N, uint16_t H, uint16_t B> inline enable_if_t<(B <= H) && (H <= N) && (N < 32), uint32_t> circularBitShiftRightHigher(uint32_t i) { // Highest H bits are numbered [N - H, N - 1] // [N - H, N - H + B - 1] are therefore the middle `B` bits (those that will become MSB) // Lowest bits numbered from 0 through N - H - 1 const uint32_t lowMask = (1 << (N - H)) - 1; const uint32_t midMask = ((1 << B) - 1) << (N - H); const uint32_t highMask = ~(lowMask | midMask); uint32_t low = i & lowMask; uint32_t mid = i & midMask; uint32_t high = i & highMask; high >>= B; mid <<= H - B; return mid | high | low; } // Same as above but it's a left-shift template<uint16_t N, uint16_t H, uint16_t B> inline enable_if_t<(B <= H) && (H <= N) && (N < 32), uint32_t> circularBitShiftLeftHigher(uint32_t i) { // Highest H bits are numbered [N - H, N - 1] // [N - B, N - 1] are therefore the highest `B` bits (those that will become LSB of the [N - H, N - 1] portion), and [N - H, N - B - 1] are the middle bits // Lowest bits numbered from 0 through N - H - 1 const uint32_t lowMask = (1 << (N - H)) - 1; const uint32_t highMask = ((1 << B) - 1) << (N - 1); const uint32_t midMask = ~(lowMask | highMask); uint32_t low = i & lowMask; uint32_t mid = i & midMask; uint32_t high = i & highMask; mid <<= B; high >>= H - B; return mid | high | low; } } //namespace impl template<uint16_t ElementsPerInvocationLog2, uint16_t WorkgroupSizeLog2> struct FFTIndexingUtils { // This function maps the index `outputIdx` in the output array of a Nabla FFT to the index `freqIdx` in the DFT such that `DFT[freqIdx] = NablaFFT[outputIdx]` // This is because Cooley-Tukey + subgroup operations end up spewing out the outputs in a weird order static inline uint32_t getDFTIndex(uint32_t outputIdx) { return impl::circularBitShiftRightHigher<FFTSizeLog2, FFTSizeLog2 - ElementsPerInvocationLog2 + 1, 1>(hlsl::bitReverseAs<uint32_t>(outputIdx, FFTSizeLog2)); } // This function maps the index `freqIdx` in the DFT to the index `idx` in the output array of a Nabla FFT such that `DFT[freqIdx] = NablaFFT[idx]` // It is essentially the inverse of `getDFTIndex` static inline uint32_t getNablaIndex(uint32_t freqIdx) { return hlsl::bitReverseAs<uint32_t>(impl::circularBitShiftLeftHigher<FFTSizeLog2, FFTSizeLog2 - ElementsPerInvocationLog2 + 1, 1>(freqIdx), FFTSizeLog2); } // Mirrors an index about the Nyquist frequency in the DFT order static inline uint32_t getDFTMirrorIndex(uint32_t freqIdx) { return (FFTSize - freqIdx) & (FFTSize - 1); } // Given an index `outputIdx` of an element into the Nabla FFT, get the index into the Nabla FFT of the element corresponding to its negative frequency static inline uint32_t getNablaMirrorIndex(uint32_t outputIdx) { return getNablaIndex(getDFTMirrorIndex(getDFTIndex(outputIdx))); } const static uint16_t FFTSizeLog2 = ElementsPerInvocationLog2 + WorkgroupSizeLog2; const static uint32_t FFTSize = uint32_t(1) << FFTSizeLog2; const static uint32_t WorkgroupSize = uint32_t(1) << WorkgroupSizeLog2; }; } } } } // ------------------------------- END COMMON --------------------------------------------- // ------------------------------- HLSL ONLY ---------------------------------------------- #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/glsl_compat/subgroup_basic.hlsl" // Copyright (C) 2023 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/glsl_compat/core.hlsl" // Copyright (C) 2023 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/spirv_intrinsics/subgroup_basic.hlsl" // Copyright (C) 2023 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/spirv_intrinsics/core.hlsl" // Copyright (C) 2023 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 11 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/spirv_intrinsics/subgroup_basic.hlsl" namespace nbl { namespace hlsl { namespace spirv { [[vk::ext_builtin_input(spv::BuiltInSubgroupSize)]] static const uint32_t SubgroupSize; [[vk::ext_builtin_input(spv::BuiltInNumSubgroups)]] static const uint32_t NumSubgroups; [[vk::ext_builtin_input(spv::BuiltInSubgroupId)]] static const uint32_t SubgroupId; [[vk::ext_builtin_input(spv::BuiltInSubgroupLocalInvocationId)]] static const uint32_t SubgroupLocalInvocationId; [[vk::ext_instruction( spv::OpGroupNonUniformElect )]] bool subgroupElect(uint32_t executionScope); } } } #line 10 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/glsl_compat/subgroup_basic.hlsl" namespace nbl { namespace hlsl { namespace glsl { // TODO: Extemely annoying that HLSL doesn't have referencies, so we can't transparently alias the variables as `const&` :( // NOTE: These are not `uint16_t` even though they could be, because IIUtSC they're `uint32_t` in SPIR-V uint32_t gl_SubgroupSize() {return spirv::SubgroupSize;} uint32_t gl_SubgroupSizeLog2() {return firstbithigh(spirv::SubgroupSize);} uint32_t gl_SubgroupInvocationID() {return spirv::SubgroupLocalInvocationId;} // only available in compute uint32_t gl_NumSubgroups() {return spirv::NumSubgroups;} uint32_t gl_SubgroupID() {return spirv::SubgroupId;} bool subgroupElect() { return spirv::subgroupElect(spv::ScopeSubgroup); } void subgroupBarrier() { spirv::controlBarrier(spv::ScopeSubgroup, spv::ScopeSubgroup, spv::MemorySemanticsImageMemoryMask | spv::MemorySemanticsWorkgroupMemoryMask | spv::MemorySemanticsUniformMemoryMask | spv::MemorySemanticsAcquireReleaseMask); } void subgroupMemoryBarrier() { spirv::memoryBarrier(spv::ScopeSubgroup, spv::MemorySemanticsImageMemoryMask | spv::MemorySemanticsWorkgroupMemoryMask | spv::MemorySemanticsUniformMemoryMask | spv::MemorySemanticsAcquireReleaseMask); } void subgroupMemoryBarrierBuffer() { spirv::memoryBarrier(spv::ScopeSubgroup, spv::MemorySemanticsAcquireReleaseMask | spv::MemorySemanticsUniformMemoryMask); } void subgroupMemoryBarrierShared() { spirv::memoryBarrier(spv::ScopeSubgroup, spv::MemorySemanticsAcquireReleaseMask | spv::MemorySemanticsWorkgroupMemoryMask); } void subgroupMemoryBarrierImage() { spirv::memoryBarrier(spv::ScopeSubgroup, spv::MemorySemanticsAcquireReleaseMask | spv::MemorySemanticsImageMemoryMask); } } } } #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/glsl_compat/subgroup_shuffle.hlsl" // Copyright (C) 2023 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/spirv_intrinsics/subgroup_shuffle.hlsl" // Copyright (C) 2023 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/spirv_intrinsics/core.hlsl" // Copyright (C) 2023 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 11 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/spirv_intrinsics/subgroup_shuffle.hlsl" namespace nbl { namespace hlsl { namespace spirv { template<typename T> [[vk::ext_capability( spv::CapabilityGroupNonUniformShuffle )]] [[vk::ext_instruction( spv::OpGroupNonUniformShuffle )]] T groupShuffle(uint32_t executionScope, T value, uint32_t invocationId); template<typename T> [[vk::ext_capability( spv::CapabilityGroupNonUniformShuffle )]] [[vk::ext_instruction( spv::OpGroupNonUniformShuffleXor )]] T groupShuffleXor(uint32_t executionScope, T value, uint32_t mask); template<typename T> [[vk::ext_capability( spv::CapabilityGroupNonUniformShuffleRelative )]] [[vk::ext_instruction( spv::OpGroupNonUniformShuffleUp )]] T groupShuffleUp(uint32_t executionScope, T value, uint32_t delta); template<typename T> [[vk::ext_capability( spv::CapabilityGroupNonUniformShuffleRelative )]] [[vk::ext_instruction( spv::OpGroupNonUniformShuffleDown )]] T groupShuffleDown(uint32_t executionScope, T value, uint32_t delta); } } } #line 9 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/glsl_compat/subgroup_shuffle.hlsl" namespace nbl { namespace hlsl { namespace glsl { template<typename T> T subgroupShuffle(T value, uint32_t invocationId) { return spirv::groupShuffle<T>(spv::ScopeSubgroup, value, invocationId); } template<typename T> T subgroupShuffleXor(T value, uint32_t mask) { return spirv::groupShuffleXor<T>(spv::ScopeSubgroup, value, mask); } template<typename T> T subgroupShuffleUp(T value, uint32_t delta) { return spirv::groupShuffleUp<T>(spv::ScopeSubgroup, value, delta); } template<typename T> T subgroupShuffleDown(T value, uint32_t delta) { return spirv::groupShuffleDown<T>(spv::ScopeSubgroup, value, delta); } } } } #line 8 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/subgroup/fft.hlsl" namespace nbl { namespace hlsl { namespace subgroup { // ----------------------------------------------------------------------------------------------------------------------------------------------------------------- template<bool Inverse, typename Scalar, class device_capabilities=void> struct FFT { static void __call([[vk::ext_reference]] inout complex_t<Scalar> lo, [[vk::ext_reference]] inout complex_t<Scalar> hi); }; // ---------------------------------------- Radix 2 forward transform - DIF ------------------------------------------------------- template<typename Scalar, class device_capabilities> struct FFT<false, Scalar, device_capabilities> { static void FFT_loop(uint32_t stride, [[vk::ext_reference]] inout complex_t<Scalar> lo, [[vk::ext_reference]] inout complex_t<Scalar> hi) { const bool topHalf = bool(glsl::gl_SubgroupInvocationID() & stride); const vector <Scalar, 2> toTrade = topHalf ? vector <Scalar, 2>(lo.real(), lo.imag()) : vector <Scalar, 2>(hi.real(), hi.imag()); const vector <Scalar, 2> exchanged = glsl::subgroupShuffleXor< vector <Scalar, 2> > (toTrade, stride); if (topHalf) { lo.real(exchanged.x); lo.imag(exchanged.y); } else { hi.real(exchanged.x); hi.imag(exchanged.y); } // Get twiddle with k = subgroupInvocation mod stride, halfN = stride fft::DIF<Scalar>::radix2(fft::twiddle<false, Scalar>(glsl::gl_SubgroupInvocationID() & (stride - 1), stride), lo, hi); } static void __call([[vk::ext_reference]] inout complex_t<Scalar> lo, [[vk::ext_reference]] inout complex_t<Scalar> hi) { const uint32_t subgroupSize = glsl::gl_SubgroupSize(); //This is N/2 // special first iteration fft::DIF<Scalar>::radix2(fft::twiddle<false, Scalar>(glsl::gl_SubgroupInvocationID(), subgroupSize), lo, hi); // Decimation in Frequency [unroll] for (uint32_t stride = subgroupSize >> 1; stride > 0; stride >>= 1) FFT_loop(stride, lo, hi); } }; // ---------------------------------------- Radix 2 inverse transform - DIT ------------------------------------------------------- template<typename Scalar, class device_capabilities> struct FFT<true, Scalar, device_capabilities> { static void FFT_loop(uint32_t stride, [[vk::ext_reference]] inout complex_t<Scalar> lo, [[vk::ext_reference]] inout complex_t<Scalar> hi) { // Get twiddle with k = subgroupInvocation mod stride, halfN = stride fft::DIT<Scalar>::radix2(fft::twiddle<true, Scalar>(glsl::gl_SubgroupInvocationID() & (stride - 1), stride), lo, hi); const bool topHalf = bool(glsl::gl_SubgroupInvocationID() & stride); const vector <Scalar, 2> toTrade = topHalf ? vector <Scalar, 2>(lo.real(), lo.imag()) : vector <Scalar, 2>(hi.real(), hi.imag()); const vector <Scalar, 2> exchanged = glsl::subgroupShuffleXor< vector <Scalar, 2> > (toTrade, stride); if (topHalf) { lo.real(exchanged.x); lo.imag(exchanged.y); } else { hi.real(exchanged.x); hi.imag(exchanged.y); } } static void __call([[vk::ext_reference]] inout complex_t<Scalar> lo, [[vk::ext_reference]] inout complex_t<Scalar> hi) { const uint32_t subgroupSize = glsl::gl_SubgroupSize(); //This is N/2 const uint32_t doubleSubgroupSize = subgroupSize << 1; //This is N // Decimation in Time [unroll] for (uint32_t stride = 1; stride < subgroupSize; stride <<= 1) FFT_loop(stride, lo, hi); // special last iteration fft::DIT<Scalar>::radix2(fft::twiddle<true, Scalar>(glsl::gl_SubgroupInvocationID(), subgroupSize), lo, hi); divides_assign< complex_t<Scalar> > divAss; divAss(lo, Scalar(doubleSubgroupSize)); divAss(hi, Scalar(doubleSubgroupSize)); } }; } } } #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/workgroup/basic.hlsl" // Copyright (C) 2023 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/glsl_compat/subgroup_ballot.hlsl" // Copyright (C) 2023 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/spirv_intrinsics/subgroup_ballot.hlsl" // Copyright (C) 2023 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/spirv_intrinsics/core.hlsl" // Copyright (C) 2023 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/spirv_intrinsics/subgroup_basic.hlsl" // Copyright (C) 2023 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 12 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/spirv_intrinsics/subgroup_ballot.hlsl" namespace nbl { namespace hlsl { namespace spirv { [[vk::ext_capability(spv::CapabilityGroupNonUniformBallot)]] [[vk::ext_builtin_input(spv::BuiltInSubgroupEqMask)]] static const uint32_t4 BuiltInSubgroupEqMask; [[vk::ext_capability(spv::CapabilityGroupNonUniformBallot)]] [[vk::ext_builtin_input(spv::BuiltInSubgroupGeMask)]] static const uint32_t4 BuiltInSubgroupGeMask; [[vk::ext_capability(spv::CapabilityGroupNonUniformBallot)]] [[vk::ext_builtin_input(spv::BuiltInSubgroupGtMask)]] static const uint32_t4 BuiltInSubgroupGtMask; [[vk::ext_capability(spv::CapabilityGroupNonUniformBallot)]] [[vk::ext_builtin_input(spv::BuiltInSubgroupLeMask)]] static const uint32_t4 BuiltInSubgroupLeMask; [[vk::ext_capability(spv::CapabilityGroupNonUniformBallot)]] [[vk::ext_builtin_input(spv::BuiltInSubgroupLtMask)]] static const uint32_t4 BuiltInSubgroupLtMask; template<typename T> [[vk::ext_capability( spv::CapabilityGroupNonUniformBallot )]] [[vk::ext_instruction( spv::OpGroupNonUniformBroadcastFirst )]] T subgroupBroadcastFirst(uint32_t executionScope, T value); template<typename T> [[vk::ext_capability( spv::CapabilityGroupNonUniformBallot )]] [[vk::ext_instruction( spv::OpGroupNonUniformBroadcast )]] T subgroupBroadcast(uint32_t executionScope, T value, uint32_t invocationId); [[vk::ext_capability( spv::CapabilityGroupNonUniformBallot )]] [[vk::ext_instruction( spv::OpGroupNonUniformBallot )]] uint32_t4 subgroupBallot(uint32_t executionScope, bool value); [[vk::ext_capability( spv::CapabilityGroupNonUniformBallot )]] [[vk::ext_instruction( spv::OpGroupNonUniformInverseBallot )]] bool subgroupInverseBallot(uint32_t executionScope, uint32_t4 value); [[vk::ext_capability( spv::CapabilityGroupNonUniformBallot )]] [[vk::ext_instruction( spv::OpGroupNonUniformBallotBitExtract )]] bool subgroupBallotBitExtract(uint32_t executionScope, uint32_t4 value, uint32_t id); [[vk::ext_capability( spv::CapabilityGroupNonUniformBallot )]] [[vk::ext_instruction( spv::OpGroupNonUniformBallotBitCount )]] uint32_t subgroupBallotBitCount(uint32_t executionScope, [[vk::ext_literal]] uint32_t operation, uint32_t4 value); [[vk::ext_capability(spv::CapabilityGroupNonUniformBallot)]] [[vk::ext_instruction(spv::OpGroupNonUniformBallotFindLSB)]] uint32_t subgroupBallotFindLSB(uint32_t executionScope, uint32_t4 value); [[vk::ext_capability(spv::CapabilityGroupNonUniformBallot)]] [[vk::ext_instruction(spv::OpGroupNonUniformBallotFindMSB)]] uint32_t subgroupBallotFindMSB(uint32_t executionScope, uint32_t4 value); } } } #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/glsl_compat/subgroup_basic.hlsl" // Copyright (C) 2023 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 10 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/glsl_compat/subgroup_ballot.hlsl" namespace nbl { namespace hlsl { namespace glsl { // TODO: Extemely annoying that HLSL doesn't have referencies, so we can't transparently alias the variables as `const&` :( uint32_t4 gl_SubgroupEqMask() {return spirv::BuiltInSubgroupEqMask;} uint32_t4 gl_SubgroupGeMask() {return spirv::BuiltInSubgroupGeMask;} uint32_t4 gl_SubgroupGtMask() {return spirv::BuiltInSubgroupGtMask;} uint32_t4 gl_SubgroupLeMask() {return spirv::BuiltInSubgroupLeMask;} uint32_t4 gl_SubgroupLtMask() {return spirv::BuiltInSubgroupLtMask;} template<typename T> T subgroupBroadcastFirst(T value) { return spirv::subgroupBroadcastFirst<T>(spv::ScopeSubgroup, value); } template<typename T> T subgroupBroadcast(T value, const uint32_t invocationId) { return spirv::subgroupBroadcast<T>(spv::ScopeSubgroup, value, invocationId); } uint32_t4 subgroupBallot(bool value) { return spirv::subgroupBallot(spv::ScopeSubgroup, value); } bool subgroupInverseBallot(uint32_t4 value) { return spirv::subgroupInverseBallot(spv::ScopeSubgroup, value); } bool subgroupBallotBitExtract(uint32_t4 value, uint32_t index) { return spirv::subgroupBallotBitExtract(spv::ScopeSubgroup, value, index); } uint32_t subgroupBallotBitCount(uint32_t4 value) { return spirv::subgroupBallotBitCount(spv::ScopeSubgroup, spv::GroupOperationReduce, value); } uint32_t subgroupBallotInclusiveBitCount(uint32_t4 value) { return spirv::subgroupBallotBitCount(spv::ScopeSubgroup, spv::GroupOperationInclusiveScan, value); } uint32_t subgroupBallotExclusiveBitCount(uint32_t4 value) { return spirv::subgroupBallotBitCount(spv::ScopeSubgroup, spv::GroupOperationExclusiveScan, value); } uint32_t subgroupBallotFindLSB(uint32_t4 value) { return spirv::subgroupBallotFindLSB(spv::ScopeSubgroup, value); } uint32_t subgroupBallotFindMSB(uint32_t4 value) { return spirv::subgroupBallotFindMSB(spv::ScopeSubgroup, value); } } } } #line 9 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/workgroup/basic.hlsl" //! all functions must be called in uniform control flow (all workgroup invocations active) namespace nbl { namespace hlsl { namespace workgroup { static const uint32_t MaxWorkgroupSizeLog2 = 11; static const uint32_t MaxWorkgroupSize = 0x1u<<MaxWorkgroupSizeLog2; uint16_t Volume() { const uint16_t3 dims = uint16_t3(glsl::gl_WorkGroupSize()); return dims.x*dims.y*dims.z; } uint16_t SubgroupContiguousIndex() { const uint16_t retval = (uint16_t(glsl::gl_SubgroupID())<<glsl::gl_SubgroupSizeLog2())+uint16_t(glsl::gl_SubgroupInvocationID()); ; return retval; } bool Elect() { return glsl::gl_SubgroupID()==0 && glsl::gl_SubgroupInvocationID()==0; } uint16_t ElectedSubgroupContiguousIndex() { return glsl::subgroupBroadcastFirst<uint16_t>(SubgroupContiguousIndex()); } } } } #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/glsl_compat/core.hlsl" // Copyright (C) 2023 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/memory_accessor.hlsl" // Copyright (C) 2023 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/glsl_compat/core.hlsl" // Copyright (C) 2023 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/member_test_macros.hlsl" // Copyright (C) 2022 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/utility.hlsl" // Copyright (C) 2024 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 16 "C:/Users/Rynair/Desktop/Nabla/3rdparty/boost/superproject/libs/preprocessor/include/boost/preprocessor/tuple/limits/to_seq_64.hpp" /* An empty array can be passed */ #line 12 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/member_test_macros.hlsl" namespace nbl { namespace hlsl { namespace impl { enum e_member_presence { is_present = 1<<0, is_static = 1<<1, is_const = 1<<2, }; template<bool=false> struct if_2_else_1 : integral_constant<uint32_t,1> {}; template<> struct if_2_else_1<true> : integral_constant<uint32_t,2> {}; } typedef impl::e_member_presence e_member_presence; } } #line 62 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/member_test_macros.hlsl" namespace nbl { namespace hlsl { namespace impl { template<class T, class=void> struct is_static_member_x: false_type { }; template<class T> struct is_static_member_x<T,typename enable_if<!is_same<__decltype(T::x),void>::value,void>::type> : true_type { }; template<class T, class=void> struct is_member_x: false_type { using type = void; }; template<class T> struct is_member_x<T,typename enable_if<!is_same<__decltype(experimental::declval<T>().x),void>::value,void>::type> : true_type { using type = __decltype(experimental::declval<T>().x); }; } template<class T> struct has_member_x { const static e_member_presence value = (e_member_presence)(impl::is_member_x<T>::value + 2*impl::is_static_member_x<T>::value + 4*is_const<typename impl::is_member_x<T>::type>::value); }; template<class T, class F> struct has_member_x_with_type : bool_constant<has_member_x<T>::value && is_same<typename impl::is_member_x<T>::type, F>::value> {}; } } namespace nbl { namespace hlsl { namespace impl { template<class T, class=void> struct is_static_member_y: false_type { }; template<class T> struct is_static_member_y<T,typename enable_if<!is_same<__decltype(T::y),void>::value,void>::type> : true_type { }; template<class T, class=void> struct is_member_y: false_type { using type = void; }; template<class T> struct is_member_y<T,typename enable_if<!is_same<__decltype(experimental::declval<T>().y),void>::value,void>::type> : true_type { using type = __decltype(experimental::declval<T>().y); }; } template<class T> struct has_member_y { const static e_member_presence value = (e_member_presence)(impl::is_member_y<T>::value + 2*impl::is_static_member_y<T>::value + 4*is_const<typename impl::is_member_y<T>::type>::value); }; template<class T, class F> struct has_member_y_with_type : bool_constant<has_member_y<T>::value && is_same<typename impl::is_member_y<T>::type, F>::value> {}; } } namespace nbl { namespace hlsl { namespace impl { template<class T, class=void> struct is_static_member_z: false_type { }; template<class T> struct is_static_member_z<T,typename enable_if<!is_same<__decltype(T::z),void>::value,void>::type> : true_type { }; template<class T, class=void> struct is_member_z: false_type { using type = void; }; template<class T> struct is_member_z<T,typename enable_if<!is_same<__decltype(experimental::declval<T>().z),void>::value,void>::type> : true_type { using type = __decltype(experimental::declval<T>().z); }; } template<class T> struct has_member_z { const static e_member_presence value = (e_member_presence)(impl::is_member_z<T>::value + 2*impl::is_static_member_z<T>::value + 4*is_const<typename impl::is_member_z<T>::type>::value); }; template<class T, class F> struct has_member_z_with_type : bool_constant<has_member_z<T>::value && is_same<typename impl::is_member_z<T>::type, F>::value> {}; } } namespace nbl { namespace hlsl { namespace impl { template<class T, class=void> struct is_static_member_w: false_type { }; template<class T> struct is_static_member_w<T,typename enable_if<!is_same<__decltype(T::w),void>::value,void>::type> : true_type { }; template<class T, class=void> struct is_member_w: false_type { using type = void; }; template<class T> struct is_member_w<T,typename enable_if<!is_same<__decltype(experimental::declval<T>().w),void>::value,void>::type> : true_type { using type = __decltype(experimental::declval<T>().w); }; } template<class T> struct has_member_w { const static e_member_presence value = (e_member_presence)(impl::is_member_w<T>::value + 2*impl::is_static_member_w<T>::value + 4*is_const<typename impl::is_member_w<T>::type>::value); }; template<class T, class F> struct has_member_w_with_type : bool_constant<has_member_w<T>::value && is_same<typename impl::is_member_w<T>::type, F>::value> {}; } } #line 95 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/member_test_macros.hlsl" /* types that are impilicitly convertible to each other mess this check up struct S { void a(int) { return 0;} }; has_method_a<S, float>::value will be true since float is implicitly convertible to int and due to how we check function signatures at the moment */ // TODO: these should probably generate without a namespace and be expected to be put inside a namespace #line 119 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/member_test_macros.hlsl" namespace nbl { namespace hlsl { namespace impl { template<typename T , typename Arg0=void , typename Arg1=void , typename Arg2=void , typename Arg3=void, class=void> struct has_static_method_a : false_type {}; template<class T > struct has_static_method_a<T , typename make_void<__decltype(T::a())>::type> : true_type { using return_type = __decltype(T::a()); const static uint arg_count = 0; }; template<class T , typename Arg0> struct has_static_method_a<T , Arg0, typename make_void<__decltype(T::a(experimental::declval<Arg0>()))>::type> : true_type { using return_type = __decltype(T::a(experimental::declval<Arg0>())); const static uint arg_count = 1; }; template<class T , typename Arg0 , typename Arg1> struct has_static_method_a<T , Arg0 , Arg1, typename make_void<__decltype(T::a(experimental::declval<Arg0>() , experimental::declval<Arg1>()))>::type> : true_type { using return_type = __decltype(T::a(experimental::declval<Arg0>() , experimental::declval<Arg1>())); const static uint arg_count = 2; }; template<class T , typename Arg0 , typename Arg1 , typename Arg2> struct has_static_method_a<T , Arg0 , Arg1 , Arg2, typename make_void<__decltype(T::a(experimental::declval<Arg0>() , experimental::declval<Arg1>() , experimental::declval<Arg2>()))>::type> : true_type { using return_type = __decltype(T::a(experimental::declval<Arg0>() , experimental::declval<Arg1>() , experimental::declval<Arg2>())); const static uint arg_count = 3; }; } template<typename T , typename Arg0=void , typename Arg1=void , typename Arg2=void , typename Arg3=void, class=void> struct has_method_a : false_type {}; template<class T > struct has_method_a<T , typename make_void<__decltype(experimental::declval<T>().a())>::type> : impl::if_2_else_1<impl::has_static_method_a<T >::value> { using return_type = __decltype(experimental::declval<T>().a()); const static uint arg_count = 0; }; template<class T , typename Arg0> struct has_method_a<T , Arg0, typename make_void<__decltype(experimental::declval<T>().a(experimental::declval<Arg0>()))>::type> : impl::if_2_else_1<impl::has_static_method_a<T , Arg0>::value> { using return_type = __decltype(experimental::declval<T>().a(experimental::declval<Arg0>())); const static uint arg_count = 1; }; template<class T , typename Arg0 , typename Arg1> struct has_method_a<T , Arg0 , Arg1, typename make_void<__decltype(experimental::declval<T>().a(experimental::declval<Arg0>() , experimental::declval<Arg1>()))>::type> : impl::if_2_else_1<impl::has_static_method_a<T , Arg0 , Arg1>::value> { using return_type = __decltype(experimental::declval<T>().a(experimental::declval<Arg0>() , experimental::declval<Arg1>())); const static uint arg_count = 2; }; template<class T , typename Arg0 , typename Arg1 , typename Arg2> struct has_method_a<T , Arg0 , Arg1 , Arg2, typename make_void<__decltype(experimental::declval<T>().a(experimental::declval<Arg0>() , experimental::declval<Arg1>() , experimental::declval<Arg2>()))>::type> : impl::if_2_else_1<impl::has_static_method_a<T , Arg0 , Arg1 , Arg2>::value> { using return_type = __decltype(experimental::declval<T>().a(experimental::declval<Arg0>() , experimental::declval<Arg1>() , experimental::declval<Arg2>())); const static uint arg_count = 3; }; }} // TODO: remove namespace nbl { namespace hlsl { namespace impl { template<typename T , typename Arg0=void , typename Arg1=void , typename Arg2=void , typename Arg3=void, class=void> struct has_static_method_b : false_type {}; template<class T > struct has_static_method_b<T , typename make_void<__decltype(T::b())>::type> : true_type { using return_type = __decltype(T::b()); const static uint arg_count = 0; }; template<class T , typename Arg0> struct has_static_method_b<T , Arg0, typename make_void<__decltype(T::b(experimental::declval<Arg0>()))>::type> : true_type { using return_type = __decltype(T::b(experimental::declval<Arg0>())); const static uint arg_count = 1; }; template<class T , typename Arg0 , typename Arg1> struct has_static_method_b<T , Arg0 , Arg1, typename make_void<__decltype(T::b(experimental::declval<Arg0>() , experimental::declval<Arg1>()))>::type> : true_type { using return_type = __decltype(T::b(experimental::declval<Arg0>() , experimental::declval<Arg1>())); const static uint arg_count = 2; }; template<class T , typename Arg0 , typename Arg1 , typename Arg2> struct has_static_method_b<T , Arg0 , Arg1 , Arg2, typename make_void<__decltype(T::b(experimental::declval<Arg0>() , experimental::declval<Arg1>() , experimental::declval<Arg2>()))>::type> : true_type { using return_type = __decltype(T::b(experimental::declval<Arg0>() , experimental::declval<Arg1>() , experimental::declval<Arg2>())); const static uint arg_count = 3; }; } template<typename T , typename Arg0=void , typename Arg1=void , typename Arg2=void , typename Arg3=void, class=void> struct has_method_b : false_type {}; template<class T > struct has_method_b<T , typename make_void<__decltype(experimental::declval<T>().b())>::type> : impl::if_2_else_1<impl::has_static_method_b<T >::value> { using return_type = __decltype(experimental::declval<T>().b()); const static uint arg_count = 0; }; template<class T , typename Arg0> struct has_method_b<T , Arg0, typename make_void<__decltype(experimental::declval<T>().b(experimental::declval<Arg0>()))>::type> : impl::if_2_else_1<impl::has_static_method_b<T , Arg0>::value> { using return_type = __decltype(experimental::declval<T>().b(experimental::declval<Arg0>())); const static uint arg_count = 1; }; template<class T , typename Arg0 , typename Arg1> struct has_method_b<T , Arg0 , Arg1, typename make_void<__decltype(experimental::declval<T>().b(experimental::declval<Arg0>() , experimental::declval<Arg1>()))>::type> : impl::if_2_else_1<impl::has_static_method_b<T , Arg0 , Arg1>::value> { using return_type = __decltype(experimental::declval<T>().b(experimental::declval<Arg0>() , experimental::declval<Arg1>())); const static uint arg_count = 2; }; template<class T , typename Arg0 , typename Arg1 , typename Arg2> struct has_method_b<T , Arg0 , Arg1 , Arg2, typename make_void<__decltype(experimental::declval<T>().b(experimental::declval<Arg0>() , experimental::declval<Arg1>() , experimental::declval<Arg2>()))>::type> : impl::if_2_else_1<impl::has_static_method_b<T , Arg0 , Arg1 , Arg2>::value> { using return_type = __decltype(experimental::declval<T>().b(experimental::declval<Arg0>() , experimental::declval<Arg1>() , experimental::declval<Arg2>())); const static uint arg_count = 3; }; }} // TODO: remove namespace nbl { namespace hlsl { namespace impl { template<typename T , typename Arg0=void , typename Arg1=void , typename Arg2=void , typename Arg3=void, class=void> struct has_static_method_get : false_type {}; template<class T > struct has_static_method_get<T , typename make_void<__decltype(T::get())>::type> : true_type { using return_type = __decltype(T::get()); const static uint arg_count = 0; }; template<class T , typename Arg0> struct has_static_method_get<T , Arg0, typename make_void<__decltype(T::get(experimental::declval<Arg0>()))>::type> : true_type { using return_type = __decltype(T::get(experimental::declval<Arg0>())); const static uint arg_count = 1; }; template<class T , typename Arg0 , typename Arg1> struct has_static_method_get<T , Arg0 , Arg1, typename make_void<__decltype(T::get(experimental::declval<Arg0>() , experimental::declval<Arg1>()))>::type> : true_type { using return_type = __decltype(T::get(experimental::declval<Arg0>() , experimental::declval<Arg1>())); const static uint arg_count = 2; }; template<class T , typename Arg0 , typename Arg1 , typename Arg2> struct has_static_method_get<T , Arg0 , Arg1 , Arg2, typename make_void<__decltype(T::get(experimental::declval<Arg0>() , experimental::declval<Arg1>() , experimental::declval<Arg2>()))>::type> : true_type { using return_type = __decltype(T::get(experimental::declval<Arg0>() , experimental::declval<Arg1>() , experimental::declval<Arg2>())); const static uint arg_count = 3; }; } template<typename T , typename Arg0=void , typename Arg1=void , typename Arg2=void , typename Arg3=void, class=void> struct has_method_get : false_type {}; template<class T > struct has_method_get<T , typename make_void<__decltype(experimental::declval<T>().get())>::type> : impl::if_2_else_1<impl::has_static_method_get<T >::value> { using return_type = __decltype(experimental::declval<T>().get()); const static uint arg_count = 0; }; template<class T , typename Arg0> struct has_method_get<T , Arg0, typename make_void<__decltype(experimental::declval<T>().get(experimental::declval<Arg0>()))>::type> : impl::if_2_else_1<impl::has_static_method_get<T , Arg0>::value> { using return_type = __decltype(experimental::declval<T>().get(experimental::declval<Arg0>())); const static uint arg_count = 1; }; template<class T , typename Arg0 , typename Arg1> struct has_method_get<T , Arg0 , Arg1, typename make_void<__decltype(experimental::declval<T>().get(experimental::declval<Arg0>() , experimental::declval<Arg1>()))>::type> : impl::if_2_else_1<impl::has_static_method_get<T , Arg0 , Arg1>::value> { using return_type = __decltype(experimental::declval<T>().get(experimental::declval<Arg0>() , experimental::declval<Arg1>())); const static uint arg_count = 2; }; template<class T , typename Arg0 , typename Arg1 , typename Arg2> struct has_method_get<T , Arg0 , Arg1 , Arg2, typename make_void<__decltype(experimental::declval<T>().get(experimental::declval<Arg0>() , experimental::declval<Arg1>() , experimental::declval<Arg2>()))>::type> : impl::if_2_else_1<impl::has_static_method_get<T , Arg0 , Arg1 , Arg2>::value> { using return_type = __decltype(experimental::declval<T>().get(experimental::declval<Arg0>() , experimental::declval<Arg1>() , experimental::declval<Arg2>())); const static uint arg_count = 3; }; }} namespace nbl { namespace hlsl { namespace impl { template<typename T , typename Arg0=void , typename Arg1=void , typename Arg2=void , typename Arg3=void, class=void> struct has_static_method_set : false_type {}; template<class T > struct has_static_method_set<T , typename make_void<__decltype(T::set())>::type> : true_type { using return_type = __decltype(T::set()); const static uint arg_count = 0; }; template<class T , typename Arg0> struct has_static_method_set<T , Arg0, typename make_void<__decltype(T::set(experimental::declval<Arg0>()))>::type> : true_type { using return_type = __decltype(T::set(experimental::declval<Arg0>())); const static uint arg_count = 1; }; template<class T , typename Arg0 , typename Arg1> struct has_static_method_set<T , Arg0 , Arg1, typename make_void<__decltype(T::set(experimental::declval<Arg0>() , experimental::declval<Arg1>()))>::type> : true_type { using return_type = __decltype(T::set(experimental::declval<Arg0>() , experimental::declval<Arg1>())); const static uint arg_count = 2; }; template<class T , typename Arg0 , typename Arg1 , typename Arg2> struct has_static_method_set<T , Arg0 , Arg1 , Arg2, typename make_void<__decltype(T::set(experimental::declval<Arg0>() , experimental::declval<Arg1>() , experimental::declval<Arg2>()))>::type> : true_type { using return_type = __decltype(T::set(experimental::declval<Arg0>() , experimental::declval<Arg1>() , experimental::declval<Arg2>())); const static uint arg_count = 3; }; } template<typename T , typename Arg0=void , typename Arg1=void , typename Arg2=void , typename Arg3=void, class=void> struct has_method_set : false_type {}; template<class T > struct has_method_set<T , typename make_void<__decltype(experimental::declval<T>().set())>::type> : impl::if_2_else_1<impl::has_static_method_set<T >::value> { using return_type = __decltype(experimental::declval<T>().set()); const static uint arg_count = 0; }; template<class T , typename Arg0> struct has_method_set<T , Arg0, typename make_void<__decltype(experimental::declval<T>().set(experimental::declval<Arg0>()))>::type> : impl::if_2_else_1<impl::has_static_method_set<T , Arg0>::value> { using return_type = __decltype(experimental::declval<T>().set(experimental::declval<Arg0>())); const static uint arg_count = 1; }; template<class T , typename Arg0 , typename Arg1> struct has_method_set<T , Arg0 , Arg1, typename make_void<__decltype(experimental::declval<T>().set(experimental::declval<Arg0>() , experimental::declval<Arg1>()))>::type> : impl::if_2_else_1<impl::has_static_method_set<T , Arg0 , Arg1>::value> { using return_type = __decltype(experimental::declval<T>().set(experimental::declval<Arg0>() , experimental::declval<Arg1>())); const static uint arg_count = 2; }; template<class T , typename Arg0 , typename Arg1 , typename Arg2> struct has_method_set<T , Arg0 , Arg1 , Arg2, typename make_void<__decltype(experimental::declval<T>().set(experimental::declval<Arg0>() , experimental::declval<Arg1>() , experimental::declval<Arg2>()))>::type> : impl::if_2_else_1<impl::has_static_method_set<T , Arg0 , Arg1 , Arg2>::value> { using return_type = __decltype(experimental::declval<T>().set(experimental::declval<Arg0>() , experimental::declval<Arg1>() , experimental::declval<Arg2>())); const static uint arg_count = 3; }; }} #line 10 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/memory_accessor.hlsl" // weird namespace placing, see the comment where the macro is defined namespace nbl { namespace hlsl { namespace impl { template<typename T , typename Arg0=void , typename Arg1=void , typename Arg2=void , typename Arg3=void, class=void> struct has_static_method_atomicExchange : false_type {}; template<class T > struct has_static_method_atomicExchange<T , typename make_void<__decltype(T::atomicExchange())>::type> : true_type { using return_type = __decltype(T::atomicExchange()); const static uint arg_count = 0; }; template<class T , typename Arg0> struct has_static_method_atomicExchange<T , Arg0, typename make_void<__decltype(T::atomicExchange(experimental::declval<Arg0>()))>::type> : true_type { using return_type = __decltype(T::atomicExchange(experimental::declval<Arg0>())); const static uint arg_count = 1; }; template<class T , typename Arg0 , typename Arg1> struct has_static_method_atomicExchange<T , Arg0 , Arg1, typename make_void<__decltype(T::atomicExchange(experimental::declval<Arg0>() , experimental::declval<Arg1>()))>::type> : true_type { using return_type = __decltype(T::atomicExchange(experimental::declval<Arg0>() , experimental::declval<Arg1>())); const static uint arg_count = 2; }; template<class T , typename Arg0 , typename Arg1 , typename Arg2> struct has_static_method_atomicExchange<T , Arg0 , Arg1 , Arg2, typename make_void<__decltype(T::atomicExchange(experimental::declval<Arg0>() , experimental::declval<Arg1>() , experimental::declval<Arg2>()))>::type> : true_type { using return_type = __decltype(T::atomicExchange(experimental::declval<Arg0>() , experimental::declval<Arg1>() , experimental::declval<Arg2>())); const static uint arg_count = 3; }; } template<typename T , typename Arg0=void , typename Arg1=void , typename Arg2=void , typename Arg3=void, class=void> struct has_method_atomicExchange : false_type {}; template<class T > struct has_method_atomicExchange<T , typename make_void<__decltype(experimental::declval<T>().atomicExchange())>::type> : impl::if_2_else_1<impl::has_static_method_atomicExchange<T >::value> { using return_type = __decltype(experimental::declval<T>().atomicExchange()); const static uint arg_count = 0; }; template<class T , typename Arg0> struct has_method_atomicExchange<T , Arg0, typename make_void<__decltype(experimental::declval<T>().atomicExchange(experimental::declval<Arg0>()))>::type> : impl::if_2_else_1<impl::has_static_method_atomicExchange<T , Arg0>::value> { using return_type = __decltype(experimental::declval<T>().atomicExchange(experimental::declval<Arg0>())); const static uint arg_count = 1; }; template<class T , typename Arg0 , typename Arg1> struct has_method_atomicExchange<T , Arg0 , Arg1, typename make_void<__decltype(experimental::declval<T>().atomicExchange(experimental::declval<Arg0>() , experimental::declval<Arg1>()))>::type> : impl::if_2_else_1<impl::has_static_method_atomicExchange<T , Arg0 , Arg1>::value> { using return_type = __decltype(experimental::declval<T>().atomicExchange(experimental::declval<Arg0>() , experimental::declval<Arg1>())); const static uint arg_count = 2; }; template<class T , typename Arg0 , typename Arg1 , typename Arg2> struct has_method_atomicExchange<T , Arg0 , Arg1 , Arg2, typename make_void<__decltype(experimental::declval<T>().atomicExchange(experimental::declval<Arg0>() , experimental::declval<Arg1>() , experimental::declval<Arg2>()))>::type> : impl::if_2_else_1<impl::has_static_method_atomicExchange<T , Arg0 , Arg1 , Arg2>::value> { using return_type = __decltype(experimental::declval<T>().atomicExchange(experimental::declval<Arg0>() , experimental::declval<Arg1>() , experimental::declval<Arg2>())); const static uint arg_count = 3; }; }} namespace nbl { namespace hlsl { namespace impl { template<typename T , typename Arg0=void , typename Arg1=void , typename Arg2=void , typename Arg3=void, class=void> struct has_static_method_atomicCompSwap : false_type {}; template<class T > struct has_static_method_atomicCompSwap<T , typename make_void<__decltype(T::atomicCompSwap())>::type> : true_type { using return_type = __decltype(T::atomicCompSwap()); const static uint arg_count = 0; }; template<class T , typename Arg0> struct has_static_method_atomicCompSwap<T , Arg0, typename make_void<__decltype(T::atomicCompSwap(experimental::declval<Arg0>()))>::type> : true_type { using return_type = __decltype(T::atomicCompSwap(experimental::declval<Arg0>())); const static uint arg_count = 1; }; template<class T , typename Arg0 , typename Arg1> struct has_static_method_atomicCompSwap<T , Arg0 , Arg1, typename make_void<__decltype(T::atomicCompSwap(experimental::declval<Arg0>() , experimental::declval<Arg1>()))>::type> : true_type { using return_type = __decltype(T::atomicCompSwap(experimental::declval<Arg0>() , experimental::declval<Arg1>())); const static uint arg_count = 2; }; template<class T , typename Arg0 , typename Arg1 , typename Arg2> struct has_static_method_atomicCompSwap<T , Arg0 , Arg1 , Arg2, typename make_void<__decltype(T::atomicCompSwap(experimental::declval<Arg0>() , experimental::declval<Arg1>() , experimental::declval<Arg2>()))>::type> : true_type { using return_type = __decltype(T::atomicCompSwap(experimental::declval<Arg0>() , experimental::declval<Arg1>() , experimental::declval<Arg2>())); const static uint arg_count = 3; }; } template<typename T , typename Arg0=void , typename Arg1=void , typename Arg2=void , typename Arg3=void, class=void> struct has_method_atomicCompSwap : false_type {}; template<class T > struct has_method_atomicCompSwap<T , typename make_void<__decltype(experimental::declval<T>().atomicCompSwap())>::type> : impl::if_2_else_1<impl::has_static_method_atomicCompSwap<T >::value> { using return_type = __decltype(experimental::declval<T>().atomicCompSwap()); const static uint arg_count = 0; }; template<class T , typename Arg0> struct has_method_atomicCompSwap<T , Arg0, typename make_void<__decltype(experimental::declval<T>().atomicCompSwap(experimental::declval<Arg0>()))>::type> : impl::if_2_else_1<impl::has_static_method_atomicCompSwap<T , Arg0>::value> { using return_type = __decltype(experimental::declval<T>().atomicCompSwap(experimental::declval<Arg0>())); const static uint arg_count = 1; }; template<class T , typename Arg0 , typename Arg1> struct has_method_atomicCompSwap<T , Arg0 , Arg1, typename make_void<__decltype(experimental::declval<T>().atomicCompSwap(experimental::declval<Arg0>() , experimental::declval<Arg1>()))>::type> : impl::if_2_else_1<impl::has_static_method_atomicCompSwap<T , Arg0 , Arg1>::value> { using return_type = __decltype(experimental::declval<T>().atomicCompSwap(experimental::declval<Arg0>() , experimental::declval<Arg1>())); const static uint arg_count = 2; }; template<class T , typename Arg0 , typename Arg1 , typename Arg2> struct has_method_atomicCompSwap<T , Arg0 , Arg1 , Arg2, typename make_void<__decltype(experimental::declval<T>().atomicCompSwap(experimental::declval<Arg0>() , experimental::declval<Arg1>() , experimental::declval<Arg2>()))>::type> : impl::if_2_else_1<impl::has_static_method_atomicCompSwap<T , Arg0 , Arg1 , Arg2>::value> { using return_type = __decltype(experimental::declval<T>().atomicCompSwap(experimental::declval<Arg0>() , experimental::declval<Arg1>() , experimental::declval<Arg2>())); const static uint arg_count = 3; }; }} namespace nbl { namespace hlsl { namespace impl { template<typename T , typename Arg0=void , typename Arg1=void , typename Arg2=void , typename Arg3=void, class=void> struct has_static_method_atomicAnd : false_type {}; template<class T > struct has_static_method_atomicAnd<T , typename make_void<__decltype(T::atomicAnd())>::type> : true_type { using return_type = __decltype(T::atomicAnd()); const static uint arg_count = 0; }; template<class T , typename Arg0> struct has_static_method_atomicAnd<T , Arg0, typename make_void<__decltype(T::atomicAnd(experimental::declval<Arg0>()))>::type> : true_type { using return_type = __decltype(T::atomicAnd(experimental::declval<Arg0>())); const static uint arg_count = 1; }; template<class T , typename Arg0 , typename Arg1> struct has_static_method_atomicAnd<T , Arg0 , Arg1, typename make_void<__decltype(T::atomicAnd(experimental::declval<Arg0>() , experimental::declval<Arg1>()))>::type> : true_type { using return_type = __decltype(T::atomicAnd(experimental::declval<Arg0>() , experimental::declval<Arg1>())); const static uint arg_count = 2; }; template<class T , typename Arg0 , typename Arg1 , typename Arg2> struct has_static_method_atomicAnd<T , Arg0 , Arg1 , Arg2, typename make_void<__decltype(T::atomicAnd(experimental::declval<Arg0>() , experimental::declval<Arg1>() , experimental::declval<Arg2>()))>::type> : true_type { using return_type = __decltype(T::atomicAnd(experimental::declval<Arg0>() , experimental::declval<Arg1>() , experimental::declval<Arg2>())); const static uint arg_count = 3; }; } template<typename T , typename Arg0=void , typename Arg1=void , typename Arg2=void , typename Arg3=void, class=void> struct has_method_atomicAnd : false_type {}; template<class T > struct has_method_atomicAnd<T , typename make_void<__decltype(experimental::declval<T>().atomicAnd())>::type> : impl::if_2_else_1<impl::has_static_method_atomicAnd<T >::value> { using return_type = __decltype(experimental::declval<T>().atomicAnd()); const static uint arg_count = 0; }; template<class T , typename Arg0> struct has_method_atomicAnd<T , Arg0, typename make_void<__decltype(experimental::declval<T>().atomicAnd(experimental::declval<Arg0>()))>::type> : impl::if_2_else_1<impl::has_static_method_atomicAnd<T , Arg0>::value> { using return_type = __decltype(experimental::declval<T>().atomicAnd(experimental::declval<Arg0>())); const static uint arg_count = 1; }; template<class T , typename Arg0 , typename Arg1> struct has_method_atomicAnd<T , Arg0 , Arg1, typename make_void<__decltype(experimental::declval<T>().atomicAnd(experimental::declval<Arg0>() , experimental::declval<Arg1>()))>::type> : impl::if_2_else_1<impl::has_static_method_atomicAnd<T , Arg0 , Arg1>::value> { using return_type = __decltype(experimental::declval<T>().atomicAnd(experimental::declval<Arg0>() , experimental::declval<Arg1>())); const static uint arg_count = 2; }; template<class T , typename Arg0 , typename Arg1 , typename Arg2> struct has_method_atomicAnd<T , Arg0 , Arg1 , Arg2, typename make_void<__decltype(experimental::declval<T>().atomicAnd(experimental::declval<Arg0>() , experimental::declval<Arg1>() , experimental::declval<Arg2>()))>::type> : impl::if_2_else_1<impl::has_static_method_atomicAnd<T , Arg0 , Arg1 , Arg2>::value> { using return_type = __decltype(experimental::declval<T>().atomicAnd(experimental::declval<Arg0>() , experimental::declval<Arg1>() , experimental::declval<Arg2>())); const static uint arg_count = 3; }; }} namespace nbl { namespace hlsl { namespace impl { template<typename T , typename Arg0=void , typename Arg1=void , typename Arg2=void , typename Arg3=void, class=void> struct has_static_method_atomicOr : false_type {}; template<class T > struct has_static_method_atomicOr<T , typename make_void<__decltype(T::atomicOr())>::type> : true_type { using return_type = __decltype(T::atomicOr()); const static uint arg_count = 0; }; template<class T , typename Arg0> struct has_static_method_atomicOr<T , Arg0, typename make_void<__decltype(T::atomicOr(experimental::declval<Arg0>()))>::type> : true_type { using return_type = __decltype(T::atomicOr(experimental::declval<Arg0>())); const static uint arg_count = 1; }; template<class T , typename Arg0 , typename Arg1> struct has_static_method_atomicOr<T , Arg0 , Arg1, typename make_void<__decltype(T::atomicOr(experimental::declval<Arg0>() , experimental::declval<Arg1>()))>::type> : true_type { using return_type = __decltype(T::atomicOr(experimental::declval<Arg0>() , experimental::declval<Arg1>())); const static uint arg_count = 2; }; template<class T , typename Arg0 , typename Arg1 , typename Arg2> struct has_static_method_atomicOr<T , Arg0 , Arg1 , Arg2, typename make_void<__decltype(T::atomicOr(experimental::declval<Arg0>() , experimental::declval<Arg1>() , experimental::declval<Arg2>()))>::type> : true_type { using return_type = __decltype(T::atomicOr(experimental::declval<Arg0>() , experimental::declval<Arg1>() , experimental::declval<Arg2>())); const static uint arg_count = 3; }; } template<typename T , typename Arg0=void , typename Arg1=void , typename Arg2=void , typename Arg3=void, class=void> struct has_method_atomicOr : false_type {}; template<class T > struct has_method_atomicOr<T , typename make_void<__decltype(experimental::declval<T>().atomicOr())>::type> : impl::if_2_else_1<impl::has_static_method_atomicOr<T >::value> { using return_type = __decltype(experimental::declval<T>().atomicOr()); const static uint arg_count = 0; }; template<class T , typename Arg0> struct has_method_atomicOr<T , Arg0, typename make_void<__decltype(experimental::declval<T>().atomicOr(experimental::declval<Arg0>()))>::type> : impl::if_2_else_1<impl::has_static_method_atomicOr<T , Arg0>::value> { using return_type = __decltype(experimental::declval<T>().atomicOr(experimental::declval<Arg0>())); const static uint arg_count = 1; }; template<class T , typename Arg0 , typename Arg1> struct has_method_atomicOr<T , Arg0 , Arg1, typename make_void<__decltype(experimental::declval<T>().atomicOr(experimental::declval<Arg0>() , experimental::declval<Arg1>()))>::type> : impl::if_2_else_1<impl::has_static_method_atomicOr<T , Arg0 , Arg1>::value> { using return_type = __decltype(experimental::declval<T>().atomicOr(experimental::declval<Arg0>() , experimental::declval<Arg1>())); const static uint arg_count = 2; }; template<class T , typename Arg0 , typename Arg1 , typename Arg2> struct has_method_atomicOr<T , Arg0 , Arg1 , Arg2, typename make_void<__decltype(experimental::declval<T>().atomicOr(experimental::declval<Arg0>() , experimental::declval<Arg1>() , experimental::declval<Arg2>()))>::type> : impl::if_2_else_1<impl::has_static_method_atomicOr<T , Arg0 , Arg1 , Arg2>::value> { using return_type = __decltype(experimental::declval<T>().atomicOr(experimental::declval<Arg0>() , experimental::declval<Arg1>() , experimental::declval<Arg2>())); const static uint arg_count = 3; }; }} namespace nbl { namespace hlsl { namespace impl { template<typename T , typename Arg0=void , typename Arg1=void , typename Arg2=void , typename Arg3=void, class=void> struct has_static_method_atomicXor : false_type {}; template<class T > struct has_static_method_atomicXor<T , typename make_void<__decltype(T::atomicXor())>::type> : true_type { using return_type = __decltype(T::atomicXor()); const static uint arg_count = 0; }; template<class T , typename Arg0> struct has_static_method_atomicXor<T , Arg0, typename make_void<__decltype(T::atomicXor(experimental::declval<Arg0>()))>::type> : true_type { using return_type = __decltype(T::atomicXor(experimental::declval<Arg0>())); const static uint arg_count = 1; }; template<class T , typename Arg0 , typename Arg1> struct has_static_method_atomicXor<T , Arg0 , Arg1, typename make_void<__decltype(T::atomicXor(experimental::declval<Arg0>() , experimental::declval<Arg1>()))>::type> : true_type { using return_type = __decltype(T::atomicXor(experimental::declval<Arg0>() , experimental::declval<Arg1>())); const static uint arg_count = 2; }; template<class T , typename Arg0 , typename Arg1 , typename Arg2> struct has_static_method_atomicXor<T , Arg0 , Arg1 , Arg2, typename make_void<__decltype(T::atomicXor(experimental::declval<Arg0>() , experimental::declval<Arg1>() , experimental::declval<Arg2>()))>::type> : true_type { using return_type = __decltype(T::atomicXor(experimental::declval<Arg0>() , experimental::declval<Arg1>() , experimental::declval<Arg2>())); const static uint arg_count = 3; }; } template<typename T , typename Arg0=void , typename Arg1=void , typename Arg2=void , typename Arg3=void, class=void> struct has_method_atomicXor : false_type {}; template<class T > struct has_method_atomicXor<T , typename make_void<__decltype(experimental::declval<T>().atomicXor())>::type> : impl::if_2_else_1<impl::has_static_method_atomicXor<T >::value> { using return_type = __decltype(experimental::declval<T>().atomicXor()); const static uint arg_count = 0; }; template<class T , typename Arg0> struct has_method_atomicXor<T , Arg0, typename make_void<__decltype(experimental::declval<T>().atomicXor(experimental::declval<Arg0>()))>::type> : impl::if_2_else_1<impl::has_static_method_atomicXor<T , Arg0>::value> { using return_type = __decltype(experimental::declval<T>().atomicXor(experimental::declval<Arg0>())); const static uint arg_count = 1; }; template<class T , typename Arg0 , typename Arg1> struct has_method_atomicXor<T , Arg0 , Arg1, typename make_void<__decltype(experimental::declval<T>().atomicXor(experimental::declval<Arg0>() , experimental::declval<Arg1>()))>::type> : impl::if_2_else_1<impl::has_static_method_atomicXor<T , Arg0 , Arg1>::value> { using return_type = __decltype(experimental::declval<T>().atomicXor(experimental::declval<Arg0>() , experimental::declval<Arg1>())); const static uint arg_count = 2; }; template<class T , typename Arg0 , typename Arg1 , typename Arg2> struct has_method_atomicXor<T , Arg0 , Arg1 , Arg2, typename make_void<__decltype(experimental::declval<T>().atomicXor(experimental::declval<Arg0>() , experimental::declval<Arg1>() , experimental::declval<Arg2>()))>::type> : impl::if_2_else_1<impl::has_static_method_atomicXor<T , Arg0 , Arg1 , Arg2>::value> { using return_type = __decltype(experimental::declval<T>().atomicXor(experimental::declval<Arg0>() , experimental::declval<Arg1>() , experimental::declval<Arg2>())); const static uint arg_count = 3; }; }} namespace nbl { namespace hlsl { namespace impl { template<typename T , typename Arg0=void , typename Arg1=void , typename Arg2=void , typename Arg3=void, class=void> struct has_static_method_atomicAdd : false_type {}; template<class T > struct has_static_method_atomicAdd<T , typename make_void<__decltype(T::atomicAdd())>::type> : true_type { using return_type = __decltype(T::atomicAdd()); const static uint arg_count = 0; }; template<class T , typename Arg0> struct has_static_method_atomicAdd<T , Arg0, typename make_void<__decltype(T::atomicAdd(experimental::declval<Arg0>()))>::type> : true_type { using return_type = __decltype(T::atomicAdd(experimental::declval<Arg0>())); const static uint arg_count = 1; }; template<class T , typename Arg0 , typename Arg1> struct has_static_method_atomicAdd<T , Arg0 , Arg1, typename make_void<__decltype(T::atomicAdd(experimental::declval<Arg0>() , experimental::declval<Arg1>()))>::type> : true_type { using return_type = __decltype(T::atomicAdd(experimental::declval<Arg0>() , experimental::declval<Arg1>())); const static uint arg_count = 2; }; template<class T , typename Arg0 , typename Arg1 , typename Arg2> struct has_static_method_atomicAdd<T , Arg0 , Arg1 , Arg2, typename make_void<__decltype(T::atomicAdd(experimental::declval<Arg0>() , experimental::declval<Arg1>() , experimental::declval<Arg2>()))>::type> : true_type { using return_type = __decltype(T::atomicAdd(experimental::declval<Arg0>() , experimental::declval<Arg1>() , experimental::declval<Arg2>())); const static uint arg_count = 3; }; } template<typename T , typename Arg0=void , typename Arg1=void , typename Arg2=void , typename Arg3=void, class=void> struct has_method_atomicAdd : false_type {}; template<class T > struct has_method_atomicAdd<T , typename make_void<__decltype(experimental::declval<T>().atomicAdd())>::type> : impl::if_2_else_1<impl::has_static_method_atomicAdd<T >::value> { using return_type = __decltype(experimental::declval<T>().atomicAdd()); const static uint arg_count = 0; }; template<class T , typename Arg0> struct has_method_atomicAdd<T , Arg0, typename make_void<__decltype(experimental::declval<T>().atomicAdd(experimental::declval<Arg0>()))>::type> : impl::if_2_else_1<impl::has_static_method_atomicAdd<T , Arg0>::value> { using return_type = __decltype(experimental::declval<T>().atomicAdd(experimental::declval<Arg0>())); const static uint arg_count = 1; }; template<class T , typename Arg0 , typename Arg1> struct has_method_atomicAdd<T , Arg0 , Arg1, typename make_void<__decltype(experimental::declval<T>().atomicAdd(experimental::declval<Arg0>() , experimental::declval<Arg1>()))>::type> : impl::if_2_else_1<impl::has_static_method_atomicAdd<T , Arg0 , Arg1>::value> { using return_type = __decltype(experimental::declval<T>().atomicAdd(experimental::declval<Arg0>() , experimental::declval<Arg1>())); const static uint arg_count = 2; }; template<class T , typename Arg0 , typename Arg1 , typename Arg2> struct has_method_atomicAdd<T , Arg0 , Arg1 , Arg2, typename make_void<__decltype(experimental::declval<T>().atomicAdd(experimental::declval<Arg0>() , experimental::declval<Arg1>() , experimental::declval<Arg2>()))>::type> : impl::if_2_else_1<impl::has_static_method_atomicAdd<T , Arg0 , Arg1 , Arg2>::value> { using return_type = __decltype(experimental::declval<T>().atomicAdd(experimental::declval<Arg0>() , experimental::declval<Arg1>() , experimental::declval<Arg2>())); const static uint arg_count = 3; }; }} namespace nbl { namespace hlsl { namespace impl { template<typename T , typename Arg0=void , typename Arg1=void , typename Arg2=void , typename Arg3=void, class=void> struct has_static_method_atomicMin : false_type {}; template<class T > struct has_static_method_atomicMin<T , typename make_void<__decltype(T::atomicMin())>::type> : true_type { using return_type = __decltype(T::atomicMin()); const static uint arg_count = 0; }; template<class T , typename Arg0> struct has_static_method_atomicMin<T , Arg0, typename make_void<__decltype(T::atomicMin(experimental::declval<Arg0>()))>::type> : true_type { using return_type = __decltype(T::atomicMin(experimental::declval<Arg0>())); const static uint arg_count = 1; }; template<class T , typename Arg0 , typename Arg1> struct has_static_method_atomicMin<T , Arg0 , Arg1, typename make_void<__decltype(T::atomicMin(experimental::declval<Arg0>() , experimental::declval<Arg1>()))>::type> : true_type { using return_type = __decltype(T::atomicMin(experimental::declval<Arg0>() , experimental::declval<Arg1>())); const static uint arg_count = 2; }; template<class T , typename Arg0 , typename Arg1 , typename Arg2> struct has_static_method_atomicMin<T , Arg0 , Arg1 , Arg2, typename make_void<__decltype(T::atomicMin(experimental::declval<Arg0>() , experimental::declval<Arg1>() , experimental::declval<Arg2>()))>::type> : true_type { using return_type = __decltype(T::atomicMin(experimental::declval<Arg0>() , experimental::declval<Arg1>() , experimental::declval<Arg2>())); const static uint arg_count = 3; }; } template<typename T , typename Arg0=void , typename Arg1=void , typename Arg2=void , typename Arg3=void, class=void> struct has_method_atomicMin : false_type {}; template<class T > struct has_method_atomicMin<T , typename make_void<__decltype(experimental::declval<T>().atomicMin())>::type> : impl::if_2_else_1<impl::has_static_method_atomicMin<T >::value> { using return_type = __decltype(experimental::declval<T>().atomicMin()); const static uint arg_count = 0; }; template<class T , typename Arg0> struct has_method_atomicMin<T , Arg0, typename make_void<__decltype(experimental::declval<T>().atomicMin(experimental::declval<Arg0>()))>::type> : impl::if_2_else_1<impl::has_static_method_atomicMin<T , Arg0>::value> { using return_type = __decltype(experimental::declval<T>().atomicMin(experimental::declval<Arg0>())); const static uint arg_count = 1; }; template<class T , typename Arg0 , typename Arg1> struct has_method_atomicMin<T , Arg0 , Arg1, typename make_void<__decltype(experimental::declval<T>().atomicMin(experimental::declval<Arg0>() , experimental::declval<Arg1>()))>::type> : impl::if_2_else_1<impl::has_static_method_atomicMin<T , Arg0 , Arg1>::value> { using return_type = __decltype(experimental::declval<T>().atomicMin(experimental::declval<Arg0>() , experimental::declval<Arg1>())); const static uint arg_count = 2; }; template<class T , typename Arg0 , typename Arg1 , typename Arg2> struct has_method_atomicMin<T , Arg0 , Arg1 , Arg2, typename make_void<__decltype(experimental::declval<T>().atomicMin(experimental::declval<Arg0>() , experimental::declval<Arg1>() , experimental::declval<Arg2>()))>::type> : impl::if_2_else_1<impl::has_static_method_atomicMin<T , Arg0 , Arg1 , Arg2>::value> { using return_type = __decltype(experimental::declval<T>().atomicMin(experimental::declval<Arg0>() , experimental::declval<Arg1>() , experimental::declval<Arg2>())); const static uint arg_count = 3; }; }} namespace nbl { namespace hlsl { namespace impl { template<typename T , typename Arg0=void , typename Arg1=void , typename Arg2=void , typename Arg3=void, class=void> struct has_static_method_atomicMax : false_type {}; template<class T > struct has_static_method_atomicMax<T , typename make_void<__decltype(T::atomicMax())>::type> : true_type { using return_type = __decltype(T::atomicMax()); const static uint arg_count = 0; }; template<class T , typename Arg0> struct has_static_method_atomicMax<T , Arg0, typename make_void<__decltype(T::atomicMax(experimental::declval<Arg0>()))>::type> : true_type { using return_type = __decltype(T::atomicMax(experimental::declval<Arg0>())); const static uint arg_count = 1; }; template<class T , typename Arg0 , typename Arg1> struct has_static_method_atomicMax<T , Arg0 , Arg1, typename make_void<__decltype(T::atomicMax(experimental::declval<Arg0>() , experimental::declval<Arg1>()))>::type> : true_type { using return_type = __decltype(T::atomicMax(experimental::declval<Arg0>() , experimental::declval<Arg1>())); const static uint arg_count = 2; }; template<class T , typename Arg0 , typename Arg1 , typename Arg2> struct has_static_method_atomicMax<T , Arg0 , Arg1 , Arg2, typename make_void<__decltype(T::atomicMax(experimental::declval<Arg0>() , experimental::declval<Arg1>() , experimental::declval<Arg2>()))>::type> : true_type { using return_type = __decltype(T::atomicMax(experimental::declval<Arg0>() , experimental::declval<Arg1>() , experimental::declval<Arg2>())); const static uint arg_count = 3; }; } template<typename T , typename Arg0=void , typename Arg1=void , typename Arg2=void , typename Arg3=void, class=void> struct has_method_atomicMax : false_type {}; template<class T > struct has_method_atomicMax<T , typename make_void<__decltype(experimental::declval<T>().atomicMax())>::type> : impl::if_2_else_1<impl::has_static_method_atomicMax<T >::value> { using return_type = __decltype(experimental::declval<T>().atomicMax()); const static uint arg_count = 0; }; template<class T , typename Arg0> struct has_method_atomicMax<T , Arg0, typename make_void<__decltype(experimental::declval<T>().atomicMax(experimental::declval<Arg0>()))>::type> : impl::if_2_else_1<impl::has_static_method_atomicMax<T , Arg0>::value> { using return_type = __decltype(experimental::declval<T>().atomicMax(experimental::declval<Arg0>())); const static uint arg_count = 1; }; template<class T , typename Arg0 , typename Arg1> struct has_method_atomicMax<T , Arg0 , Arg1, typename make_void<__decltype(experimental::declval<T>().atomicMax(experimental::declval<Arg0>() , experimental::declval<Arg1>()))>::type> : impl::if_2_else_1<impl::has_static_method_atomicMax<T , Arg0 , Arg1>::value> { using return_type = __decltype(experimental::declval<T>().atomicMax(experimental::declval<Arg0>() , experimental::declval<Arg1>())); const static uint arg_count = 2; }; template<class T , typename Arg0 , typename Arg1 , typename Arg2> struct has_method_atomicMax<T , Arg0 , Arg1 , Arg2, typename make_void<__decltype(experimental::declval<T>().atomicMax(experimental::declval<Arg0>() , experimental::declval<Arg1>() , experimental::declval<Arg2>()))>::type> : impl::if_2_else_1<impl::has_static_method_atomicMax<T , Arg0 , Arg1 , Arg2>::value> { using return_type = __decltype(experimental::declval<T>().atomicMax(experimental::declval<Arg0>() , experimental::declval<Arg1>() , experimental::declval<Arg2>())); const static uint arg_count = 3; }; }} namespace nbl { namespace hlsl { namespace impl { template<typename T , typename Arg0=void , typename Arg1=void , typename Arg2=void , typename Arg3=void, class=void> struct has_static_method_workgroupExecutionAndMemoryBarrier : false_type {}; template<class T > struct has_static_method_workgroupExecutionAndMemoryBarrier<T , typename make_void<__decltype(T::workgroupExecutionAndMemoryBarrier())>::type> : true_type { using return_type = __decltype(T::workgroupExecutionAndMemoryBarrier()); const static uint arg_count = 0; }; template<class T , typename Arg0> struct has_static_method_workgroupExecutionAndMemoryBarrier<T , Arg0, typename make_void<__decltype(T::workgroupExecutionAndMemoryBarrier(experimental::declval<Arg0>()))>::type> : true_type { using return_type = __decltype(T::workgroupExecutionAndMemoryBarrier(experimental::declval<Arg0>())); const static uint arg_count = 1; }; template<class T , typename Arg0 , typename Arg1> struct has_static_method_workgroupExecutionAndMemoryBarrier<T , Arg0 , Arg1, typename make_void<__decltype(T::workgroupExecutionAndMemoryBarrier(experimental::declval<Arg0>() , experimental::declval<Arg1>()))>::type> : true_type { using return_type = __decltype(T::workgroupExecutionAndMemoryBarrier(experimental::declval<Arg0>() , experimental::declval<Arg1>())); const static uint arg_count = 2; }; template<class T , typename Arg0 , typename Arg1 , typename Arg2> struct has_static_method_workgroupExecutionAndMemoryBarrier<T , Arg0 , Arg1 , Arg2, typename make_void<__decltype(T::workgroupExecutionAndMemoryBarrier(experimental::declval<Arg0>() , experimental::declval<Arg1>() , experimental::declval<Arg2>()))>::type> : true_type { using return_type = __decltype(T::workgroupExecutionAndMemoryBarrier(experimental::declval<Arg0>() , experimental::declval<Arg1>() , experimental::declval<Arg2>())); const static uint arg_count = 3; }; } template<typename T , typename Arg0=void , typename Arg1=void , typename Arg2=void , typename Arg3=void, class=void> struct has_method_workgroupExecutionAndMemoryBarrier : false_type {}; template<class T > struct has_method_workgroupExecutionAndMemoryBarrier<T , typename make_void<__decltype(experimental::declval<T>().workgroupExecutionAndMemoryBarrier())>::type> : impl::if_2_else_1<impl::has_static_method_workgroupExecutionAndMemoryBarrier<T >::value> { using return_type = __decltype(experimental::declval<T>().workgroupExecutionAndMemoryBarrier()); const static uint arg_count = 0; }; template<class T , typename Arg0> struct has_method_workgroupExecutionAndMemoryBarrier<T , Arg0, typename make_void<__decltype(experimental::declval<T>().workgroupExecutionAndMemoryBarrier(experimental::declval<Arg0>()))>::type> : impl::if_2_else_1<impl::has_static_method_workgroupExecutionAndMemoryBarrier<T , Arg0>::value> { using return_type = __decltype(experimental::declval<T>().workgroupExecutionAndMemoryBarrier(experimental::declval<Arg0>())); const static uint arg_count = 1; }; template<class T , typename Arg0 , typename Arg1> struct has_method_workgroupExecutionAndMemoryBarrier<T , Arg0 , Arg1, typename make_void<__decltype(experimental::declval<T>().workgroupExecutionAndMemoryBarrier(experimental::declval<Arg0>() , experimental::declval<Arg1>()))>::type> : impl::if_2_else_1<impl::has_static_method_workgroupExecutionAndMemoryBarrier<T , Arg0 , Arg1>::value> { using return_type = __decltype(experimental::declval<T>().workgroupExecutionAndMemoryBarrier(experimental::declval<Arg0>() , experimental::declval<Arg1>())); const static uint arg_count = 2; }; template<class T , typename Arg0 , typename Arg1 , typename Arg2> struct has_method_workgroupExecutionAndMemoryBarrier<T , Arg0 , Arg1 , Arg2, typename make_void<__decltype(experimental::declval<T>().workgroupExecutionAndMemoryBarrier(experimental::declval<Arg0>() , experimental::declval<Arg1>() , experimental::declval<Arg2>()))>::type> : impl::if_2_else_1<impl::has_static_method_workgroupExecutionAndMemoryBarrier<T , Arg0 , Arg1 , Arg2>::value> { using return_type = __decltype(experimental::declval<T>().workgroupExecutionAndMemoryBarrier(experimental::declval<Arg0>() , experimental::declval<Arg1>() , experimental::declval<Arg2>())); const static uint arg_count = 3; }; }} namespace nbl { namespace hlsl { // TODO: flesh out and move to `nbl/builtin/hlsl/utility.hlsl` template<typename T1, typename T2> struct pair { using first_type = T1; using second_type = T2; first_type first; second_type second; }; namespace accessor_adaptors { namespace impl { // only base class to use integral_constant because we need to use void to indicate a dynamic value and all values are valid template<typename IndexType, typename Offset> struct OffsetBase { const static IndexType offset = Offset::value; }; template<typename IndexType> struct OffsetBase<IndexType,void> { IndexType offset; }; template<typename IndexType, uint64_t ElementStride, uint64_t SubElementStride, typename Offset> struct StructureOfArraysStrides { const static IndexType elementStride = ElementStride; const static IndexType subElementStride = SubElementStride; //static_assert(elementStride>0 && subElementStride>0); }; template<typename IndexType, typename Offset> struct StructureOfArraysStrides<IndexType,0,0,Offset> : OffsetBase<IndexType,Offset> { IndexType elementStride; IndexType subElementStride; }; #line 83 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/memory_accessor.hlsl" template<typename IndexType, uint64_t ElementStride, uint64_t SubElementStride, typename Offset> struct StructureOfArraysBase : StructureOfArraysStrides<IndexType,ElementStride,SubElementStride,Offset> { IndexType getIx(const IndexType ix, const IndexType el) { using base_t = StructureOfArraysStrides<IndexType,ElementStride,SubElementStride,Offset>; return base_t::elementStride*ix+base_t::subElementStride*el+OffsetBase<IndexType,Offset>::offset; } }; // maybe we should have our own std::array template<typename T, uint64_t count> struct array { T data[count]; }; } // TODO: some CRTP thing to forward through atomics and barriers // If you want static strides pass `Stride=pair<integral_constant<IndexType,ElementStride>,integral_constant<IndexType,SubElementStride> >` template<class BaseAccessor, typename AccessType, typename IndexType=uint32_t, uint64_t ElementStride=0, uint64_t SubElementStride=0, typename _Offset=integral_constant<IndexType,0> > struct StructureOfArrays : impl::StructureOfArraysBase<IndexType,ElementStride,SubElementStride,_Offset> { using base_t = impl::StructureOfArraysBase<IndexType,ElementStride,SubElementStride,_Offset>; // Question: should the `BaseAccessor` let us know what this is? using access_t = AccessType; using index_t = IndexType; BaseAccessor accessor; // Question: shall we go back to requiring a `access_t get(index_t)` on the `BaseAccessor`, then we could `enable_if` check the return type (via `has_method_get`) matches and we won't get Nasty HLSL copy-in copy-out conversions template<typename T, typename I=index_t> enable_if_t<sizeof(T)%sizeof(access_t)==0,void> get(const I ix, [[vk::ext_reference]] inout T value) { const static uint64_t SubElementCount = sizeof(T)/sizeof(access_t); // `vector` for now, we'll use `array` later when `bit_cast` gets fixed vector<access_t,SubElementCount> aux; for (index_t i=0; i<SubElementCount; i++) accessor.get(base_t::getIx(ix,i),aux[i]); value = bit_cast<T,vector<access_t,SubElementCount> >(aux); } template<typename T, typename I=index_t> enable_if_t<sizeof(T)%sizeof(access_t)==0,void> set(const I ix, const in T value) { const static uint64_t SubElementCount = sizeof(T)/sizeof(access_t); // `vector` for now, we'll use `array` later when `bit_cast` gets fixed vector<access_t,SubElementCount> aux; aux = bit_cast<vector<access_t,SubElementCount>,T>(value); for (index_t i=0; i<SubElementCount; i++) accessor.set(base_t::getIx(ix,i),aux[i]); } template<typename T, typename S=BaseAccessor> enable_if_t< sizeof(T)==sizeof(access_t) && is_same_v<S,BaseAccessor> && is_same_v<typename has_method_atomicExchange<S,index_t,access_t>::return_type,access_t>,void > atomicExchange(const index_t ix, const T value, [[vk::ext_reference]] inout T orig) { orig = bit_cast<T,access_t>(accessor.atomicExchange(getIx(ix),bit_cast<access_t,T>(value))); } template<typename T, typename S=BaseAccessor> enable_if_t< sizeof(T)==sizeof(access_t) && is_same_v<S,BaseAccessor> && is_same_v<typename has_method_atomicCompSwap<S,index_t,access_t,access_t>::return_type,access_t>,void > atomicCompSwap(const index_t ix, const T value, const T comp, [[vk::ext_reference]] inout T orig) { orig = bit_cast<T,access_t>(accessor.atomicCompSwap(getIx(ix),bit_cast<access_t,T>(comp),bit_cast<access_t,T>(value))); } template<typename T, typename S=BaseAccessor> enable_if_t< sizeof(T)==sizeof(access_t) && is_same_v<S,BaseAccessor> && is_same_v<typename has_method_atomicAnd<S,index_t,access_t>::return_type,access_t>,void > atomicAnd(const index_t ix, const T value, [[vk::ext_reference]] inout T orig) { orig = bit_cast<T,access_t>(accessor.atomicAnd(getIx(ix),bit_cast<access_t,T>(value))); } template<typename T, typename S=BaseAccessor> enable_if_t< sizeof(T)==sizeof(access_t) && is_same_v<S,BaseAccessor> && is_same_v<typename has_method_atomicOr<S,index_t,access_t>::return_type,access_t>,void > atomicOr(const index_t ix, const T value, [[vk::ext_reference]] inout T orig) { orig = bit_cast<T,access_t>(accessor.atomicOr(getIx(ix),bit_cast<access_t,T>(value))); } template<typename T, typename S=BaseAccessor> enable_if_t< sizeof(T)==sizeof(access_t) && is_same_v<S,BaseAccessor> && is_same_v<typename has_method_atomicXor<S,index_t,access_t>::return_type,access_t>,void > atomicXor(const index_t ix, const T value, [[vk::ext_reference]] inout T orig) { orig = bit_cast<T,access_t>(accessor.atomicXor(getIx(ix),bit_cast<access_t,T>(value))); } // This has the upside of never calling a `(uint32_t)(uint32_t,uint32_t)` overload of `atomicAdd` because it checks the return type! // If someone makes a `(float)(uint32_t,uint32_t)` they will break this detection code, but oh well. template<typename T> enable_if_t<is_same_v<typename has_method_atomicAdd<BaseAccessor,index_t,T>::return_type,T>,void> atomicAdd(const index_t ix, const T value, [[vk::ext_reference]] inout T orig) { orig = accessor.atomicAdd(getIx(ix),value); } template<typename T> enable_if_t<is_same_v<typename has_method_atomicMin<BaseAccessor,index_t,T>::return_type,T>,void> atomicMin(const index_t ix, const T value, [[vk::ext_reference]] inout T orig) { orig = accessor.atomicMin(getIx(ix),value); } template<typename T> enable_if_t<is_same_v<typename has_method_atomicMax<BaseAccessor,index_t,T>::return_type,T>,void> atomicMax(const index_t ix, const T value, [[vk::ext_reference]] inout T orig) { orig = accessor.atomicMax(getIx(ix),value); } template<typename S=BaseAccessor> enable_if_t< is_same_v<S,BaseAccessor> && is_same_v<typename has_method_workgroupExecutionAndMemoryBarrier<S>::return_type,void>,void > workgroupExecutionAndMemoryBarrier() { accessor.workgroupExecutionAndMemoryBarrier(); } }; // ---------------------------------------------- Offset Accessor ---------------------------------------------------- template<class BaseAccessor, typename IndexType=uint32_t, typename _Offset=void> struct Offset : impl::OffsetBase<IndexType,_Offset> { using base_t = impl::OffsetBase<IndexType,_Offset>; using index_t = IndexType; BaseAccessor accessor; template <typename T, typename I=index_t> void set(I idx, T value) {accessor.set(idx+base_t::offset,value); } template <typename T, typename I=index_t> void get(I idx, [[vk::ext_reference]] inout T value) {accessor.get(idx+base_t::offset,value);} template<typename S=BaseAccessor> enable_if_t< is_same_v<S,BaseAccessor> && is_same_v<typename has_method_workgroupExecutionAndMemoryBarrier<S>::return_type,void>,void > workgroupExecutionAndMemoryBarrier() { accessor.workgroupExecutionAndMemoryBarrier(); } }; } } } #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/functional.hlsl" // Copyright (C) 2023 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 7 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/workgroup/shuffle.hlsl" // TODO: Add other shuffles // We assume the accessor in the adaptor is clean and unaliased when calling this function, but we don't enforce this after the shuffle namespace nbl { namespace hlsl { namespace workgroup { // ------------------------------------- Skeletons for implementing other Shuffles -------------------------------- template<typename SharedMemoryAdaptor, typename T> struct Shuffle { static void __call([[vk::ext_reference]] inout T value, uint32_t storeIdx, uint32_t loadIdx, [[vk::ext_reference]] inout SharedMemoryAdaptor sharedmemAdaptor) { // TODO: optimization (optional) where we shuffle in the shared memory available (using rounds) sharedmemAdaptor.template set<T>(storeIdx, value); // Wait until all writes are done before reading sharedmemAdaptor.workgroupExecutionAndMemoryBarrier(); sharedmemAdaptor.template get<T>(loadIdx, value); } // By default store to threadID in the workgroup static void __call([[vk::ext_reference]] inout T value, uint32_t loadIdx, [[vk::ext_reference]] inout SharedMemoryAdaptor sharedmemAdaptor) { __call(value, uint32_t(SubgroupContiguousIndex()), loadIdx, sharedmemAdaptor); } }; template<class UnOp, typename SharedMemoryAdaptor, typename T> struct ShuffleUnOp { static void __call([[vk::ext_reference]] inout T value, uint32_t a, [[vk::ext_reference]] inout SharedMemoryAdaptor sharedmemAdaptor) { UnOp unop; // TODO: optimization (optional) where we shuffle in the shared memory available (using rounds) sharedmemAdaptor.template set<T>(a, value); // Wait until all writes are done before reading sharedmemAdaptor.workgroupExecutionAndMemoryBarrier(); sharedmemAdaptor.template get<T>(unop(a), value); } // By default store to threadID's index and load from unop(threadID) static void __call([[vk::ext_reference]] inout T value, [[vk::ext_reference]] inout SharedMemoryAdaptor sharedmemAdaptor) { __call(value, uint32_t(SubgroupContiguousIndex()), sharedmemAdaptor); } }; template<class BinOp, typename SharedMemoryAdaptor, typename T> struct ShuffleBinOp { static void __call([[vk::ext_reference]] inout T value, uint32_t a, uint32_t b, [[vk::ext_reference]] inout SharedMemoryAdaptor sharedmemAdaptor) { BinOp binop; // TODO: optimization (optional) where we shuffle in the shared memory available (using rounds) sharedmemAdaptor.template set<T>(a, value); // Wait until all writes are done before reading sharedmemAdaptor.workgroupExecutionAndMemoryBarrier(); sharedmemAdaptor.template get<T>(binop(a, b), value); } // By default first argument of binary op is the thread's ID in the workgroup static void __call([[vk::ext_reference]] inout T value, uint32_t b, [[vk::ext_reference]] inout SharedMemoryAdaptor sharedmemAdaptor) { __call(value, uint32_t(SubgroupContiguousIndex()), b, sharedmemAdaptor); } }; // ------------------------------------------ ShuffleXor --------------------------------------------------------------- template<typename SharedMemoryAdaptor, typename T> void shuffleXor([[vk::ext_reference]] inout T value, uint32_t threadID, uint32_t mask, [[vk::ext_reference]] inout SharedMemoryAdaptor sharedmemAdaptor) { return ShuffleBinOp<bit_xor<uint32_t>, SharedMemoryAdaptor, T>::__call(value, threadID, mask, sharedmemAdaptor); } template<typename SharedMemoryAdaptor, typename T> void shuffleXor([[vk::ext_reference]] inout T value, uint32_t mask, [[vk::ext_reference]] inout SharedMemoryAdaptor sharedmemAdaptor) { return ShuffleBinOp<bit_xor<uint32_t>, SharedMemoryAdaptor, T>::__call(value, mask, sharedmemAdaptor); } } } } #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/mpl.hlsl" // Copyright (C) 2022 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/type_traits.hlsl" // Copyright (C) 2022 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 12 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/mpl.hlsl" namespace nbl { namespace hlsl { namespace mpl { namespace impl { template<uint64_t N, uint16_t bits> struct countl_zero { const static uint64_t SHIFT = bits >> 1; const static uint64_t LO_MASK = (1ull << SHIFT) - 1; const static bool CHOOSE_HIGH = (N & (LO_MASK << SHIFT))!=0; const static uint64_t NEXT = (CHOOSE_HIGH ? (N >> SHIFT) : N) & LO_MASK; const static uint16_t value = countl_zero<NEXT, SHIFT>::value + (CHOOSE_HIGH ? 0ull : SHIFT); }; template<uint64_t N> struct countl_zero<N, 1> : integral_constant<uint16_t, uint16_t(1u - (N & 1))> {}; } template<class T, T N> struct countl_zero : impl::countl_zero<uint64_t(N), (sizeof(T) * 8)> { _Static_assert(is_integral<T>::value, "countl_zero type parameter must be an integral type"); }; template<class T, T N> const static T countl_zero_v = countl_zero<T,N>::value; template<uint64_t N> struct is_pot : bool_constant< (N > 0 && !(N & (N - 1))) > {}; template<uint64_t N> const static bool is_pot_v = is_pot<N>::value; template<uint64_t X> struct log2 { const static uint16_t value = X ? (1ull<<6)-countl_zero<uint64_t, X>::value-1 : -1ull; }; template<uint64_t X> const static uint16_t log2_v = log2<X>::value; template<uint64_t X> struct log2_ceil : integral_constant<uint16_t, log2_v<X> + uint16_t(!is_pot_v<X>)> {}; template<uint64_t X> const static uint16_t log2_ceil_v = log2_ceil<X>::value; template<typename T, T X, int32_t S> struct rotl { const static uint32_t N = 32u; const static int32_t r = S % N; const static T value = (S >= 0) ? ((X << r) | (X >> (N - r))) : (X >> (-r)) | (X << (N - (-r))); }; template<typename T, T X, int32_t S> const static T rotl_v = rotl<T,X,S>::value; template<typename T, T X, int32_t S> struct rotr { const static uint32_t N = 32u; const static int32_t r = S % N; const static T value = (S >= 0) ? ((X >> r) | (X << (N - r))) : (X << (-r)) | (X >> (N - (-r))); }; template<typename T, T X, int32_t S> const static T rotr_v = rotr<T,X,S>::value; template<uint64_t X, uint64_t M> struct align_up { const static uint64_t value = X ? (((X-1)/M+1)*M):0; }; template<uint64_t X, uint64_t M> const static uint64_t align_up_v = align_up<X,M>::value; template<typename T, T X, T Y> struct max { const static T value = X<Y ? Y:X; }; template<typename T, T X, T Y> const static T max_v = max<T,X,Y>::value; template<typename T, T X, T Y> struct min { const static T value = X<Y ? X:Y; }; template<typename T, T X, T Y> const static T min_v = min<T,X,Y>::value; template<uint64_t X> struct round_up_to_pot : integral_constant<uint64_t, uint64_t(1) << log2_ceil_v<X> > {}; template<uint64_t X> const static uint64_t round_up_to_pot_v = round_up_to_pot<X>::value; template<uint64_t X> struct round_down_to_pot : integral_constant<uint64_t, uint64_t(1) << log2_v<X> > {}; template<uint64_t X> const static uint64_t round_down_to_pot_v = round_down_to_pot<X>::value; } } } #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/memory_accessor.hlsl" // Copyright (C) 2023 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts.hlsl" // Copyright (C) 2023-2024 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 6 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts/accessors/generic_shared_data.hlsl" namespace nbl { namespace hlsl { namespace concepts { namespace accessors { #line 21 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts/accessors/generic_shared_data.hlsl" namespace __concept__GenericSharedMemoryAccessor { #line 25 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts/accessors/generic_shared_data.hlsl" template<typename T , typename V , typename I, typename=void> struct __requirement0 : ::nbl::hlsl::false_type {}; template<typename T , typename V , typename I> struct __requirement0<T, V, I, ::nbl::hlsl::enable_if_t< is_same_v<__decltype(::nbl::hlsl::experimental::declval< T >().template set<V,I>(::nbl::hlsl::experimental::declval< I >(), ::nbl::hlsl::experimental::declval< V >())) , void > > > : ::nbl::hlsl::true_type {}; template<typename T , typename V , typename I, typename=void> struct __requirement1 : ::nbl::hlsl::false_type {}; template<typename T , typename V , typename I> struct __requirement1<T, V, I, ::nbl::hlsl::enable_if_t< is_same_v<__decltype(::nbl::hlsl::experimental::declval< T >().template get<V,I>(::nbl::hlsl::experimental::declval< I >(), ::nbl::hlsl::experimental::declval< V >())) , void > > > : ::nbl::hlsl::true_type {}; template<typename T , typename V , typename I, typename=void> struct __requirement2 : ::nbl::hlsl::false_type {}; template<typename T , typename V , typename I> struct __requirement2<T, V, I, ::nbl::hlsl::enable_if_t< is_same_v<__decltype(::nbl::hlsl::experimental::declval< T >().workgroupExecutionAndMemoryBarrier()) , void > > > : ::nbl::hlsl::true_type {}; } template<typename T , typename V , typename I> const static bool GenericSharedMemoryAccessor = __concept__GenericSharedMemoryAccessor::__requirement0<T, V, I>::value && __concept__GenericSharedMemoryAccessor::__requirement1<T, V, I>::value && __concept__GenericSharedMemoryAccessor::__requirement2<T, V, I>::value; #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts/__end.hlsl" // Copyright (C) 2023-2024 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 41 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts/accessors/generic_shared_data.hlsl" namespace __concept__GenericReadAccessor { #line 45 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts/accessors/generic_shared_data.hlsl" template<typename T , typename V , typename I, typename=void> struct __requirement0 : ::nbl::hlsl::false_type {}; template<typename T , typename V , typename I> struct __requirement0<T, V, I, ::nbl::hlsl::enable_if_t< is_same_v<__decltype(::nbl::hlsl::experimental::declval< T >().template get<V,I>(::nbl::hlsl::experimental::declval< I >(), ::nbl::hlsl::experimental::declval< V >())) , void > > > : ::nbl::hlsl::true_type {}; } template<typename T , typename V , typename I> const static bool GenericReadAccessor = __concept__GenericReadAccessor::__requirement0<T, V, I>::value; #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts/__end.hlsl" // Copyright (C) 2023-2024 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 59 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts/accessors/generic_shared_data.hlsl" namespace __concept__GenericWriteAccessor { #line 63 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts/accessors/generic_shared_data.hlsl" template<typename T , typename V , typename I, typename=void> struct __requirement0 : ::nbl::hlsl::false_type {}; template<typename T , typename V , typename I> struct __requirement0<T, V, I, ::nbl::hlsl::enable_if_t< is_same_v<__decltype(::nbl::hlsl::experimental::declval< T >().template set<V,I>(::nbl::hlsl::experimental::declval< I >(), ::nbl::hlsl::experimental::declval< V >())) , void > > > : ::nbl::hlsl::true_type {}; } template<typename T , typename V , typename I> const static bool GenericWriteAccessor = __concept__GenericWriteAccessor::__requirement0<T, V, I>::value; #line 1 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts/__end.hlsl" // Copyright (C) 2023-2024 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h #line 71 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts/accessors/generic_shared_data.hlsl" template<typename T, typename V, typename I=uint32_t> const static bool GenericDataAccessor = GenericWriteAccessor<T,V,I> && GenericWriteAccessor<T,V,I>; } } } } #line 7 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/concepts/accessors/fft.hlsl" namespace nbl { namespace hlsl { namespace workgroup { namespace fft { // The SharedMemoryAccessor MUST provide the following methods: // * void get(uint32_t index, NBL_REF_ARG(uint32_t) value); // * void set(uint32_t index, in uint32_t value); // * void workgroupExecutionAndMemoryBarrier(); template<typename T, typename V=uint32_t, typename I=uint32_t> const static bool FFTSharedMemoryAccessor = concepts::accessors::GenericSharedMemoryAccessor<T,V,I>; // The Accessor (for a small FFT) MUST provide the following methods: // * void get(uint32_t index, NBL_REF_ARG(complex_t<Scalar>) value); // * void set(uint32_t index, in complex_t<Scalar> value); template<typename T, typename Scalar, typename I=uint32_t> const static bool FFTAccessor = concepts::accessors::GenericDataAccessor<T,complex_t<Scalar>,I>; } } } } #line 182 "C:/Users/Rynair/Desktop/Nabla/include/nbl/builtin/hlsl/workgroup/fft.hlsl" // Caveats // - Sin and Cos in HLSL take 32-bit floats. Using this library with 64-bit floats works perfectly fine, but DXC will emit warnings // This also means that you don't really get the full precision of 64-bit since twiddle factors are only 32-bit precision namespace nbl { namespace hlsl { namespace workgroup { namespace fft { // ---------------------------------- Utils ----------------------------------------------- // No need to expose these namespace impl { template<typename SharedMemoryAdaptor, typename Scalar> struct exchangeValues { static void __call([[vk::ext_reference]] inout complex_t<Scalar> lo, [[vk::ext_reference]] inout complex_t<Scalar> hi, uint32_t threadID, uint32_t stride, [[vk::ext_reference]] inout SharedMemoryAdaptor sharedmemAdaptor) { const bool topHalf = bool(threadID & stride); // Pack into float vector because ternary operator does not support structs vector<Scalar, 2> exchanged = topHalf ? vector<Scalar, 2>(lo.real(), lo.imag()) : vector<Scalar, 2>(hi.real(), hi.imag()); shuffleXor<SharedMemoryAdaptor, vector<Scalar, 2> >(exchanged, stride, sharedmemAdaptor); if (topHalf) { lo.real(exchanged.x); lo.imag(exchanged.y); } else { hi.real(exchanged.x); hi.imag(exchanged.y); } } }; } //namespace impl template<uint16_t ElementsPerInvocationLog2, uint16_t WorkgroupSizeLog2> struct FFTMirrorTradeUtils { using indexing_utils_t = FFTIndexingUtils<ElementsPerInvocationLog2, WorkgroupSizeLog2>; // When unpacking an FFT of two packed signals, given a `globalElementIndex` you need its "mirror index" to unpack the value at NablaFFT[globalElementIndex]. // The function above has you covered in that sense, but what also happens is that not only does the thread holding `NablaFFT[globalElementIndex]` need its mirror value // but also the thread holding said mirror value will at the same time be trying to unpack `NFFT[someOtherIndex]` and need the mirror value of that. // As long as this unpacking is happening concurrently and in order (meaning the local element index - the higher bits - of `globalElementIndex` and `someOtherIndex` is the // same) then this function returns both the SubgroupContiguousIndex of the other thread AND the local element index of *the mirror* of `someOtherIndex` struct NablaMirrorLocalInfo { uint32_t otherThreadID; uint32_t mirrorLocalIndex; }; static NablaMirrorLocalInfo getNablaMirrorLocalInfo(uint32_t globalElementIndex) { const uint32_t otherElementIndex = indexing_utils_t::getNablaMirrorIndex(globalElementIndex); const uint32_t mirrorLocalIndex = otherElementIndex / WorkgroupSize; const uint32_t otherThreadID = otherElementIndex & (WorkgroupSize - 1); const NablaMirrorLocalInfo info = { otherThreadID, mirrorLocalIndex }; return info; } // Like the above, but return global indices instead. struct NablaMirrorGlobalInfo { uint32_t otherThreadID; uint32_t mirrorGlobalIndex; }; static NablaMirrorGlobalInfo getNablaMirrorGlobalInfo(uint32_t globalElementIndex) { const uint32_t otherElementIndex = indexing_utils_t::getNablaMirrorIndex(globalElementIndex); const uint32_t mirrorGlobalIndex = glsl::bitfieldInsert<uint32_t>(otherElementIndex, workgroup::SubgroupContiguousIndex(), 0, uint32_t(WorkgroupSizeLog2)); const uint32_t otherThreadID = otherElementIndex & (WorkgroupSize - 1); const NablaMirrorGlobalInfo info = { otherThreadID, mirrorGlobalIndex }; return info; } // If trading elements when, for example, unpacking real FFTs, you might do so from within your accessor or from outside. // If doing so from within your accessor, particularly if using a preloaded accessor, you might want to do this yourself by // using FFTIndexingUtils::getNablaMirrorTradeInfo and trading the elements yourself (an example of how to set this up is given in // the FFT Bloom example, in the `fft_mirror_common.hlsl` file). // If you're doing this from outside your preloaded accessor then you might want to use this method instead. // Note: you can still pass a preloaded accessor as `arrayAccessor` here, it's just that you're going to be doing extra computations for the indices. template<typename scalar_t, typename fft_array_accessor_t, typename shared_memory_adaptor_t> static complex_t<scalar_t> getNablaMirror(uint32_t globalElementIndex, fft_array_accessor_t arrayAccessor, shared_memory_adaptor_t sharedmemAdaptor) { const NablaMirrorGlobalInfo mirrorInfo = getNablaMirrorGlobalInfo(globalElementIndex); complex_t<scalar_t> toTrade = arrayAccessor.get(mirrorInfo.mirrorGlobalIndex); vector<scalar_t, 2> toTradeVector = { toTrade.real(), toTrade.imag() }; workgroup::Shuffle<shared_memory_adaptor_t, vector<scalar_t, 2> >::__call(toTradeVector, mirrorInfo.otherThreadID, sharedmemAdaptor); toTrade.real(toTradeVector.x); toTrade.imag(toTradeVector.y); return toTrade; } const static indexing_utils_t IndexingUtils; const static uint32_t WorkgroupSize = indexing_utils_t::WorkgroupSize; }; } //namespace fft // ----------------------------------- End Utils -------------------------------------------------------------- template<bool Inverse, typename consteval_params_t, class device_capabilities=void> struct FFT; // For the FFT methods below, we assume: // - Accessor is an accessor to an array fitting ElementsPerInvocation * WorkgroupSize elements of type complex_t<Scalar>, used to get inputs / set outputs of the FFT. // If `ConstevalParameters::ElementsPerInvocationLog2 == 1`, the arrays it accesses with `get` and `set` can optionally be different, // if you don't want the FFT to be done in-place. Otherwise, you MUST make it in-place. // The Accessor MUST provide the following methods: // * void get(uint32_t index, NBL_REF_ARG(complex_t<Scalar>) value); // * void set(uint32_t index, in complex_t<Scalar> value); // * void memoryBarrier(); // For it to work correctly, this memory barrier must use `AcquireRelease` semantics, with the proper flags set for the memory type. // If using `ConstevalParameters::ElementsPerInvocationLog2 == 1` the Accessor IS ALLOWED TO not provide this last method. // If not needing it (such as when using preloaded accessors) we still require the method to exist but you can just make it do nothing. // - SharedMemoryAccessor accesses a workgroup-shared memory array of size `WorkgroupSize` elements of type complex_t<Scalar>. // The SharedMemoryAccessor MUST provide the following methods: // * void get(uint32_t index, NBL_REF_ARG(uint32_t) value); // * void set(uint32_t index, in uint32_t value); // * void workgroupExecutionAndMemoryBarrier(); // 2 items per invocation forward specialization template<uint16_t WorkgroupSizeLog2, typename Scalar, class device_capabilities> struct FFT<false, fft::ConstevalParameters<1, WorkgroupSizeLog2, Scalar>, device_capabilities> { using consteval_params_t = fft::ConstevalParameters<1, WorkgroupSizeLog2, Scalar>; template<typename SharedMemoryAdaptor> static void FFT_loop(uint32_t stride, [[vk::ext_reference]] inout complex_t<Scalar> lo, [[vk::ext_reference]] inout complex_t<Scalar> hi, uint32_t threadID, [[vk::ext_reference]] inout SharedMemoryAdaptor sharedmemAdaptor) { fft::impl::exchangeValues<SharedMemoryAdaptor, Scalar>::__call(lo, hi, threadID, stride, sharedmemAdaptor); // Get twiddle with k = threadID mod stride, halfN = stride hlsl::fft::DIF<Scalar>::radix2(hlsl::fft::twiddle<false, Scalar>(threadID & (stride - 1), stride), lo, hi); } template<typename Accessor, typename SharedMemoryAccessor ,::nbl::hlsl::enable_if_t<(fft::FFTAccessor<Accessor, Scalar> && fft::FFTSharedMemoryAccessor<SharedMemoryAccessor>),bool> = true> static void __call([[vk::ext_reference]] inout Accessor accessor, [[vk::ext_reference]] inout SharedMemoryAccessor sharedmemAccessor) { const uint16_t WorkgroupSize = consteval_params_t::WorkgroupSize; // Compute the indices only once const uint32_t threadID = uint32_t(SubgroupContiguousIndex()); const uint32_t loIx = threadID; const uint32_t hiIx = WorkgroupSize | loIx; // Read lo, hi values from global memory complex_t<Scalar> lo, hi; accessor.get(loIx, lo); accessor.get(hiIx, hi); // If for some reason you're running a small FFT, skip all the bigger-than-subgroup steps if (WorkgroupSize > glsl::gl_SubgroupSize()) { // Set up the memory adaptor using adaptor_t = accessor_adaptors::StructureOfArrays<SharedMemoryAccessor,uint32_t,uint32_t,1,WorkgroupSize>; adaptor_t sharedmemAdaptor; sharedmemAdaptor.accessor = sharedmemAccessor; // special first iteration hlsl::fft::DIF<Scalar>::radix2(hlsl::fft::twiddle<false, Scalar>(threadID, WorkgroupSize), lo, hi); // Run bigger steps until Subgroup-sized [unroll] for (uint32_t stride = WorkgroupSize >> 1; stride > glsl::gl_SubgroupSize(); stride >>= 1) { FFT_loop< adaptor_t >(stride, lo, hi, threadID, sharedmemAdaptor); sharedmemAdaptor.workgroupExecutionAndMemoryBarrier(); } // special last workgroup-shuffle fft::impl::exchangeValues<adaptor_t, Scalar>::__call(lo, hi, threadID, glsl::gl_SubgroupSize(), sharedmemAdaptor); // Remember to update the accessor's state sharedmemAccessor = sharedmemAdaptor.accessor; } // Subgroup-sized FFT subgroup::FFT<false, Scalar, device_capabilities>::__call(lo, hi); // Put values back in global mem accessor.set(loIx, lo); accessor.set(hiIx, hi); } }; // 2 items per invocation inverse specialization template<uint16_t WorkgroupSizeLog2, typename Scalar, class device_capabilities> struct FFT<true, fft::ConstevalParameters<1, WorkgroupSizeLog2, Scalar>, device_capabilities> { using consteval_params_t = fft::ConstevalParameters<1, WorkgroupSizeLog2, Scalar>; template<typename SharedMemoryAdaptor> static void FFT_loop(uint32_t stride, [[vk::ext_reference]] inout complex_t<Scalar> lo, [[vk::ext_reference]] inout complex_t<Scalar> hi, uint32_t threadID, [[vk::ext_reference]] inout SharedMemoryAdaptor sharedmemAdaptor) { // Get twiddle with k = threadID mod stride, halfN = stride hlsl::fft::DIT<Scalar>::radix2(hlsl::fft::twiddle<true, Scalar>(threadID & (stride - 1), stride), lo, hi); fft::impl::exchangeValues<SharedMemoryAdaptor, Scalar>::__call(lo, hi, threadID, stride, sharedmemAdaptor); } template<typename Accessor, typename SharedMemoryAccessor ,::nbl::hlsl::enable_if_t<(fft::FFTAccessor<Accessor, Scalar> && fft::FFTSharedMemoryAccessor<SharedMemoryAccessor>),bool> = true> static void __call([[vk::ext_reference]] inout Accessor accessor, [[vk::ext_reference]] inout SharedMemoryAccessor sharedmemAccessor) { const uint16_t WorkgroupSize = consteval_params_t::WorkgroupSize; // Compute the indices only once const uint32_t threadID = uint32_t(SubgroupContiguousIndex()); const uint32_t loIx = threadID; const uint32_t hiIx = WorkgroupSize | loIx; // Read lo, hi values from global memory complex_t<Scalar> lo, hi; accessor.get(loIx, lo); accessor.get(hiIx, hi); // Run a subgroup-sized FFT, then continue with bigger steps subgroup::FFT<true, Scalar, device_capabilities>::__call(lo, hi); // If for some reason you're running a small FFT, skip all the bigger-than-subgroup steps if (WorkgroupSize > glsl::gl_SubgroupSize()) { // Set up the memory adaptor using adaptor_t = accessor_adaptors::StructureOfArrays<SharedMemoryAccessor,uint32_t,uint32_t,1,WorkgroupSize>; adaptor_t sharedmemAdaptor; sharedmemAdaptor.accessor = sharedmemAccessor; // special first workgroup-shuffle fft::impl::exchangeValues<adaptor_t, Scalar>::__call(lo, hi, threadID, glsl::gl_SubgroupSize(), sharedmemAdaptor); // The bigger steps [unroll] for (uint32_t stride = glsl::gl_SubgroupSize() << 1; stride < WorkgroupSize; stride <<= 1) { // Order of waiting for shared mem writes is also reversed here, since the shuffle came earlier sharedmemAdaptor.workgroupExecutionAndMemoryBarrier(); FFT_loop< adaptor_t >(stride, lo, hi, threadID, sharedmemAdaptor); } // special last iteration hlsl::fft::DIT<Scalar>::radix2(hlsl::fft::twiddle<true, Scalar>(threadID, WorkgroupSize), lo, hi); divides_assign< complex_t<Scalar> > divAss; divAss(lo, Scalar(WorkgroupSize / glsl::gl_SubgroupSize())); divAss(hi, Scalar(WorkgroupSize / glsl::gl_SubgroupSize())); // Remember to update the accessor's state sharedmemAccessor = sharedmemAdaptor.accessor; } // Put values back in global mem accessor.set(loIx, lo); accessor.set(hiIx, hi); } }; // Forward FFT template<uint16_t ElementsPerInvocationLog2, uint16_t WorkgroupSizeLog2, typename Scalar, class device_capabilities> struct FFT<false, fft::ConstevalParameters<ElementsPerInvocationLog2, WorkgroupSizeLog2, Scalar>, device_capabilities> { using consteval_params_t = fft::ConstevalParameters<ElementsPerInvocationLog2, WorkgroupSizeLog2, Scalar>; using small_fft_consteval_params_t = fft::ConstevalParameters<1, WorkgroupSizeLog2, Scalar>; template<typename Accessor, typename SharedMemoryAccessor ,::nbl::hlsl::enable_if_t<(fft::FFTAccessor<Accessor, Scalar> && fft::FFTSharedMemoryAccessor<SharedMemoryAccessor>),bool> = true> static void __call([[vk::ext_reference]] inout Accessor accessor, [[vk::ext_reference]] inout SharedMemoryAccessor sharedmemAccessor) { const uint16_t WorkgroupSize = consteval_params_t::WorkgroupSize; const uint16_t ElementsPerInvocation = consteval_params_t::ElementsPerInvocation; [unroll] for (uint32_t stride = (ElementsPerInvocation / 2) * WorkgroupSize; stride > WorkgroupSize; stride >>= 1) { [unroll] for (uint32_t virtualThreadID = SubgroupContiguousIndex(); virtualThreadID < (ElementsPerInvocation / 2) * WorkgroupSize; virtualThreadID += WorkgroupSize) { const uint32_t loIx = ((virtualThreadID & (~(stride - 1))) << 1) | (virtualThreadID & (stride - 1)); const uint32_t hiIx = loIx | stride; complex_t<Scalar> lo, hi; accessor.get(loIx, lo); accessor.get(hiIx, hi); hlsl::fft::DIF<Scalar>::radix2(hlsl::fft::twiddle<false,Scalar>(virtualThreadID & (stride - 1), stride),lo,hi); accessor.set(loIx, lo); accessor.set(hiIx, hi); } } // do ElementsPerInvocation/2 small workgroup FFTs accessor_adaptors::Offset<Accessor> offsetAccessor; offsetAccessor.accessor = accessor; [unroll] for (uint32_t k = 0; k < ElementsPerInvocation; k += 2) { if (k) sharedmemAccessor.workgroupExecutionAndMemoryBarrier(); offsetAccessor.offset = WorkgroupSize*k; FFT<false, small_fft_consteval_params_t, device_capabilities>::template __call(offsetAccessor,sharedmemAccessor); } accessor = offsetAccessor.accessor; } }; // Inverse FFT template<uint16_t ElementsPerInvocationLog2, uint16_t WorkgroupSizeLog2, typename Scalar, class device_capabilities> struct FFT<true, fft::ConstevalParameters<ElementsPerInvocationLog2, WorkgroupSizeLog2, Scalar>, device_capabilities> { using consteval_params_t = fft::ConstevalParameters<ElementsPerInvocationLog2, WorkgroupSizeLog2, Scalar>; using small_fft_consteval_params_t = fft::ConstevalParameters<1, WorkgroupSizeLog2, Scalar>; template<typename Accessor, typename SharedMemoryAccessor ,::nbl::hlsl::enable_if_t<(fft::FFTAccessor<Accessor, Scalar> && fft::FFTSharedMemoryAccessor<SharedMemoryAccessor>),bool> = true> static void __call([[vk::ext_reference]] inout Accessor accessor, [[vk::ext_reference]] inout SharedMemoryAccessor sharedmemAccessor) { const uint16_t WorkgroupSize = consteval_params_t::WorkgroupSize; const uint16_t ElementsPerInvocation = consteval_params_t::ElementsPerInvocation; // do K/2 small workgroup FFTs accessor_adaptors::Offset<Accessor> offsetAccessor; offsetAccessor.accessor = accessor; [unroll] for (uint32_t k = 0; k < ElementsPerInvocation; k += 2) { if (k) sharedmemAccessor.workgroupExecutionAndMemoryBarrier(); offsetAccessor.offset = WorkgroupSize*k; FFT<true, small_fft_consteval_params_t, device_capabilities>::template __call(offsetAccessor,sharedmemAccessor); } accessor = offsetAccessor.accessor; [unroll] for (uint32_t stride = 2 * WorkgroupSize; stride < ElementsPerInvocation * WorkgroupSize; stride <<= 1) { [unroll] for (uint32_t virtualThreadID = SubgroupContiguousIndex(); virtualThreadID < (ElementsPerInvocation / 2) * WorkgroupSize; virtualThreadID += WorkgroupSize) { const uint32_t loIx = ((virtualThreadID & (~(stride - 1))) << 1) | (virtualThreadID & (stride - 1)); const uint32_t hiIx = loIx | stride; complex_t<Scalar> lo, hi; accessor.get(loIx, lo); accessor.get(hiIx, hi); hlsl::fft::DIT<Scalar>::radix2(hlsl::fft::twiddle<true,Scalar>(virtualThreadID & (stride - 1), stride), lo,hi); // Divide by special factor at the end if ( (ElementsPerInvocation / 2) * WorkgroupSize == stride) { divides_assign< complex_t<Scalar> > divAss; divAss(lo, ElementsPerInvocation / 2); divAss(hi, ElementsPerInvocation / 2); } accessor.set(loIx, lo); accessor.set(hiIx, hi); } } } }; } } } // ------------------------------- END HLSL ONLY ---------------------------------------------- #line 4 "C:/Users/Rynair/Desktop/Nabla/examples_tests/11_FFT/app_resources/shader.comp.hlsl" [[vk::push_constant]] PushConstantData pushConstants; using namespace nbl::hlsl; using ConstevalParameters = workgroup::fft::ConstevalParameters<ElementsPerThreadLog2, WorkgroupSizeLog2, scalar_t>; groupshared uint32_t sharedmem[ ConstevalParameters::SharedMemoryDWORDs]; // Users MUST define this method for FFT to work uint32_t3 glsl::gl_WorkGroupSize() { return uint32_t3(uint32_t(ConstevalParameters::WorkgroupSize), 1, 1); } struct SharedMemoryAccessor { template <typename AccessType, typename IndexType> void set(IndexType idx, AccessType value) { sharedmem[idx] = value; } template <typename AccessType, typename IndexType> void get(IndexType idx, [[vk::ext_reference]] inout AccessType value) { value = sharedmem[idx]; } void workgroupExecutionAndMemoryBarrier() { glsl::barrier(); } }; // Almost a LegacyBdaAccessor, but since we need `uint32_t index` getter and setter it's the same as writing one ourselves struct Accessor { static Accessor create(const uint64_t address) { Accessor accessor; accessor.address = address; return accessor; } // TODO: can't use our own BDA yet, because it doesn't support the types `workgroup::FFT` will invoke these templates with template <typename AccessType, typename IndexType> void get(const IndexType index, [[vk::ext_reference]] inout AccessType value) { value = vk::RawBufferLoad<AccessType>(address + index * sizeof(AccessType)); } template <typename AccessType, typename IndexType> void set(const IndexType index, const AccessType value) { vk::RawBufferStore<AccessType>(address + index * sizeof(AccessType), value); } uint64_t address; }; [numthreads(ConstevalParameters::WorkgroupSize,1,1)] [shader("compute")] void main(uint32_t3 ID : SV_DispatchThreadID) { Accessor accessor = Accessor::create(pushConstants.deviceBufferAddress); SharedMemoryAccessor sharedmemAccessor; // FFT workgroup::FFT<false, ConstevalParameters>::template __call<Accessor, SharedMemoryAccessor>(accessor, sharedmemAccessor); sharedmemAccessor.workgroupExecutionAndMemoryBarrier(); workgroup::FFT<true, ConstevalParameters>::template __call<Accessor, SharedMemoryAccessor>(accessor, sharedmemAccessor); }
Become a Patron
Sponsor on GitHub
Donate via PayPal
Compiler Explorer Shop
Source on GitHub
Mailing list
Installed libraries
Wiki
Report an issue
How it works
Contact the author
CE on Mastodon
CE on Bluesky
Statistics
Changelog
Version tree