yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
28758e0e4
master
1#pragma once 2 3#include "slang-signal.h" 4#include "slang.h" 5 6#include <assert.h> 7#include <cstddef> 8#include <cstring> 9#include <stdint.h> 10#include <type_traits> 11 12#define VARIADIC_TEMPLATE 13 14namespace Slang 15{ 16 17/// Signed 32-bit integer. 18/// 19/// This type should be used when the exact size 20/// in bits is important (e.g., when dealing with 21/// explicit binary file formats, etc.). Otherwise 22/// prefer the plain `Int` type or a semantically 23/// richer type like `Count` or `Index`. 24/// 25typedef int32_t Int32 ; 26 27/// Unsigned 32-bit integer. 28/// 29/// This type should be used when the exact size 30/// in bits is important (e.g., when dealing with 31/// explicit binary file formats, etc.). Otherwise 32/// prefer the plain `Int` type or a semantically 33/// richer type like `Count` or `Index`. 34/// 35typedef uint32_t UInt32 ; 36 37/// Signed 64-bit integer. 38/// 39/// This type should be used when the exact size 40/// in bits is important (e.g., when dealing with 41/// explicit binary file formats, etc.). Otherwise 42/// prefer the plain `Int` type or a semantically 43/// richer type like `Count` or `Index`. 44/// 45typedef int64_t Int64 ; 46 47/// Unsigned 64-bit integer. 48/// 49/// This type should be used when the exact size 50/// in bits is important (e.g., when dealing with 51/// explicit binary file formats, etc.). Otherwise 52/// prefer the plain `Int` type or a semantically 53/// richer type like `Count` or `Index`. 54/// 55typedef uint64_t UInt64 ; 56 57/// "Default" integer type for the Slang codebase. 58/// 59/// When there is not a clear reason to another 60/// integer type, use this one. 61/// 62/// Note that this type is currently defined to be 63/// the same as the `SlangInt` type exposed through 64/// the public Slang API, but this may not be the 65/// case forever. 66/// 67typedef SlangInt Int ; 68 69/// "Default" unsigned integer type for the Slang codebase. 70/// 71/// Only use this type when you explicitly need 72/// an unsigned type that's the same size as `Int`. 73/// Otherwise you should probably just be using `Int`. 74/// 75/// Note that this type is currently defined to be 76/// the same as the `SlangUInt` type exposed through 77/// the public Slang API, but this may not be the 78/// case forever. 79/// 80typedef SlangUInt UInt ; 81 82static const UInt kMaxUInt = ~UInt (0 ); 83static const Int kMaxInt = Int (kMaxUInt >>1 ); 84 85typedef intptr_t PtrInt ; 86 87/// Default type for indices. 88/// 89/// This is (and should always be) an alias for `Int`. 90/// 91/// Use this type to document the intention that an 92/// integer parameter/variable/etc. represents an 93/// index into some kind of sequence, or any other 94/// kind of ordinal number. 95/// 96typedef Int Index ; 97 98static const Index kMaxIndex = kMaxInt ; 99 100/// Unsigned equivalent of `Index`. 101/// 102/// Please don't use this unless you have a good reason. 103/// 104typedef UInt UIndex ; 105 106/// Default type for counts. 107/// 108/// This is (and should always be) an alias for `Int`. 109/// 110/// Use this type to document the intention that an 111/// integer parameter/variable/etc. represents a 112/// count of the number of elements in some container, 113/// or any other kind of cardinal number. 114/// 115typedef Int Count ; 116 117/// Unsigned equivalent of `Count`. 118/// 119/// Please don't use this unless you have a good reason. 120/// 121typedef UInt UCount ; 122 123 124/// Explicit type for when manipulating bytes. 125/// 126/// Use this type to document the intention that a 127/// parameter/variable/etc. represents an 8-bit byte, with 128/// no particular interpretation of that byte as 129/// any higher-level type. 130/// 131/// Note that the `char` types have special semantics 132/// when it comes to "type punning" that are not shared 133/// with other types like `uint8_t`. Using a variation 134/// of `char` here helps avoid the possibility of undefined 135/// behavior when code reads other types to/from arrays 136/// of `Byte`s. 137/// 138/// We are not using `std::byte` here because that is 139/// defined as an `enum class` and does not support 140/// mathematical or bitwise operations, which a lot 141/// of the Slang codebase does on `Byte`s. 142/// 143typedef unsigned char Byte ; 144 145/// Preferred integer type for sizes measured in bytes. 146/// 147/// Use this type to document the intention that an 148/// integer parameter/variable/etc. represents the 149/// size of something, in bytes, rather than being 150/// some other kind of integer. 151/// 152/// Note that this type is unsigned, despite the stated 153/// default in the Slang codebase being signed integer 154/// types. The reason for this is that variables 155/// holding sizes are often compared against the 156/// result of the `sizeof` operator, which yields 157/// a `size_t`. Our hands are, to some extent, tied 158/// on this matter. 159/// 160using Size = size_t ; 161 162// TODO(JS): 163// Perhaps these should be named Utf8, Utf16 and UnicodePoint/Rune/etc? For now, just keep it simple 164// 165typedef char Char8 ; 166// 16 bit character. Note much like in utf8, a character may or may not represent a code point (it 167// can be part of a code point). 168typedef uint16_t Char16 ; 169 170// Can always hold a unicode code point. 171typedef uint32_t Char32 ; 172 173template < typename T > 174inline T && _Move (T & obj ) 175{ 176return static_cast < T &&> (obj ); 177} 178 179template < typename T > 180inline void Swap (T & v0 ,T & v1 ) 181{ 182T tmp = _Move (v0 ); 183v0 = _Move (v1 ); 184v1 = _Move (tmp ); 185} 186 187// Make these interfaces have more convenient names 188typedef ISlangCastable ICastable ; 189typedef ISlangClonable IClonable ; 190 191// Convenience function for using clonable 192template < typename T > 193SLANG_FORCE_INLINE T * clone (IClonable * clonable ) 194{ 195return (T * )clonable -> clone (T ::getTypeGuid ()); 196} 197 198template < typename T > 199inline bool isBitSet (T value ,T bitToTest ) 200{ 201static_assert (sizeof (T ) <=sizeof (uint32_t ),"Only support up to 32 bit enums" ); 202return (T )((uint32_t )value & (uint32_t )bitToTest )== bitToTest ; 203} 204 205template < typename To ,typename From > 206typename std ::enable_if_t < 207sizeof (To )== sizeof (From )&& std ::is_trivially_copyable_v < From > && 208std ::is_trivially_copyable_v < To > && std ::is_trivially_constructible_v < To > , 209To > 210bitCast (const From & src ) 211{ 212To dst ; 213std ::memcpy (& dst ,& src ,sizeof (To )); 214return dst ; 215} 216 217}// namespace Slang 218 219// SLANG_DEFER 220template < typename F > 221class SlangDeferImpl 222{ 223F f ; 224 225public : 226SlangDeferImpl (F && f ) 227 :f (Slang ::_Move (f )) 228 { 229 } 230 ~SlangDeferImpl () {f (); } 231}; 232 233#ifndef SLANG_DEFER_LAMBDA 234#define SLANG_DEFER_LAMBDA (x ) auto SLANG_CONCAT(slang_defer_, __LINE__) = SlangDeferImpl(x) 235#define SLANG_DEFER (x ) auto SLANG_CONCAT(slang_defer_, __LINE__) = SlangDeferImpl([&]() { x; }) 236#endif 237 238// 239// Some macros for avoiding boilerplate 240// TODO: could probably deduce the size with templates, and move the whole 241// thing into a template 242// 243#if __cplusplus >=202002L 244#define SLANG_COMPONENTWISE_EQUALITY_1 (type ) bool operator==(const type& other) const = default; 245#define SLANG_COMPONENTWISE_EQUALITY_2 (type ) bool operator==(const type& other) const = default; 246#define SLANG_COMPONENTWISE_EQUALITY_3 (type ) bool operator==(const type& other) const = default; 247#else 248#define SLANG_COMPONENTWISE_EQUALITY_1 (type ) \ 249 bool operator==(const type& other) const \ 250 { \ 251 const auto& [m1] = *this; \ 252 const auto& [o1] = other; \ 253 return m1 == o1; \ 254 } \ 255 bool operator!=(const type& other) const \ 256 { \ 257 return !(*this == other); \ 258 } 259 260#define SLANG_COMPONENTWISE_EQUALITY_2 (type ) \ 261 bool operator==(const type& other) const \ 262 { \ 263 const auto& [m1, m2] = *this; \ 264 const auto& [o1, o2] = other; \ 265 return m1 == o1 && m2 == o2; \ 266 } \ 267 bool operator!=(const type& other) const \ 268 { \ 269 return !(*this == other); \ 270 } 271 272#define SLANG_COMPONENTWISE_EQUALITY_3 (type ) \ 273 bool operator==(const type& other) const \ 274 { \ 275 const auto& [m1, m2, m3] = *this; \ 276 const auto& [o1, o2, o3] = other; \ 277 return m1 == o1 && m2 == o2 && m3 == o3; \ 278 } \ 279 bool operator!=(const type& other) const \ 280 { \ 281 return !(*this == other); \ 282 } 283#endif 284 285// TODO: Shouldn't these be SLANG_ prefixed? 286#ifdef _MSC_VER 287#define UNREACHABLE_RETURN (x ) 288#else 289#define UNREACHABLE_RETURN (x ) return x; 290#endif 291 292#if SLANG_GCC 293#define SLANG_EXHAUSTIVE_SWITCH_BEGIN \ 294 _Pragma("GCC diagnostic push"); \ 295 _Pragma("GCC diagnostic error \"-Wswitch-enum\""); 296#define SLANG_EXHAUSTIVE_SWITCH_END _Pragma("GCC diagnostic pop"); 297#elif SLANG_CLANG 298#define SLANG_EXHAUSTIVE_SWITCH_BEGIN \ 299 _Pragma("clang diagnostic push"); \ 300 _Pragma("clang diagnostic error \"-Wswitch-enum\""); 301#define SLANG_EXHAUSTIVE_SWITCH_END _Pragma("clang diagnostic pop"); 302#elif SLANG_VC 303#define SLANG_EXHAUSTIVE_SWITCH_BEGIN \ 304 _Pragma("warning(push)"); \ 305 _Pragma("warning(error : 4062)"); 306#define SLANG_EXHAUSTIVE_SWITCH_END _Pragma("warning(pop)"); 307#else 308#define SLANG_EXHAUSTIVE_SWITCH_BEGIN 309#define SLANG_EXHAUSTIVE_SWITCH_END 310#endif 311 312#if SLANG_GCC 313#define SLANG_ALLOW_DEPRECATED_BEGIN \ 314 _Pragma("GCC diagnostic push"); \ 315 _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\""); 316#define SLANG_ALLOW_DEPRECATED_END _Pragma("GCC diagnostic pop"); 317#elif SLANG_CLANG 318#define SLANG_ALLOW_DEPRECATED_BEGIN \ 319 _Pragma("clang diagnostic push"); \ 320 _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\""); 321#define SLANG_ALLOW_DEPRECATED_END _Pragma("clang diagnostic pop"); 322#elif SLANG_VC 323#define SLANG_ALLOW_DEPRECATED_BEGIN \ 324 _Pragma("warning(push)"); \ 325 _Pragma("warning(disable : 4996)"); 326#define SLANG_ALLOW_DEPRECATED_END _Pragma("warning(pop)"); 327#else 328#define SLANG_ALLOW_DEPRECATED_BEGIN 329#define SLANG_ALLOW_DEPRECATED_END 330#endif 331 332// 333// Use `SLANG_ASSUME(myBoolExpression);` to inform the compiler that the condition is true. 334// Do not rely on side effects of the condition being performed. 335// 336#if defined(__cpp_assume ) 337#define SLANG_ASSUME (X ) [[assume(X)]] 338#elif SLANG_GCC 339#define SLANG_ASSUME (X ) \ 340 do \ 341 { \ 342 if (!(X)) \ 343 __builtin_unreachable(); \ 344 } while (0) 345#elif SLANG_CLANG 346#define SLANG_ASSUME (X ) __builtin_assume(X) 347#elif SLANG_VC 348#define SLANG_ASSUME (X ) __assume(X) 349#else 350[[noreturn ]]inline void invokeUndefinedBehaviour () {} 351#define SLANG_ASSUME (X ) \ 352 do \ 353 { \ 354 if (!(X)) \ 355 invokeUndefinedBehaviour(); \ 356 } while (0) 357#endif 358 359// 360// Assertions abort in debug builds, but inform the compiler of true 361// assumptions in release builds 362// 363#ifdef _DEBUG 364#define SLANG_ASSERT (VALUE ) \ 365 do \ 366 { \ 367 if (!(VALUE)) [[unlikely]] \ 368 SLANG_ASSERT_FAILURE(#VALUE); \ 369 } while (0) 370#else 371#define SLANG_ASSERT (VALUE ) SLANG_ASSUME(VALUE) 372#endif 373 374#define SLANG_RELEASE_ASSERT (VALUE ) \ 375 if (VALUE) [[likely]] \ 376 { \ 377 } \ 378 else \ 379 SLANG_ASSERT_FAILURE(#VALUE) 380 381template < typename T > 382void slang_use_obj (T & ) 383{ 384} 385 386#define SLANG_UNREFERENCED_PARAMETER (P )slang_use_obj (P ) 387#define SLANG_UNREFERENCED_VARIABLE (P )slang_use_obj (P ) 388 389#if defined(SLANG_RT_DYNAMIC ) 390#if defined(_MSC_VER ) 391#ifdef SLANG_RT_DYNAMIC_EXPORT 392#define SLANG_RT_API SLANG_DLL_EXPORT 393#else 394#define SLANG_RT_API __declspec(dllimport) 395#endif 396#else 397// TODO: need to consider compiler capabilities 398// # ifdef SLANG_RT_DYNAMIC_EXPORT 399#define SLANG_RT_API SLANG_DLL_EXPORT 400// # endif 401#endif 402#endif 403 404#if defined(_MSC_VER ) 405#define SLANG_ATTR_PRINTF (string_index ,varargs_index ) 406#else 407#define SLANG_ATTR_PRINTF (string_index ,varargs_index ) \ 408 __attribute__((format(printf, string_index, varargs_index))) 409#endif 410 411#ifndef SLANG_RT_API 412#define SLANG_RT_API 413#endif