1 /**************************************************************************
3 * Copyright 2013-2014 RAD Game Tools and Valve Software
4 * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 **************************************************************************/
30 #if defined(VOGL_USE_LINUX_API)
33 #include "vogl_core.h"
35 #define VOGL_OFFSETOF(t, e) ((uint32)(intptr_t)(&((t *)(0))->e))
37 #define VOGL_MIN(a, b) (((a) < (b)) ? (a) : (b))
38 #define VOGL_MAX(a, b) (((a) < (b)) ? (b) : (a))
40 #define VOGL_GLUER(a, b) a##b
43 // Need to explictly extern these with MSVC, but not MinGW.
44 extern "C" unsigned long __cdecl _lrotl(unsigned long, int);
45 #pragma intrinsic(_lrotl)
47 extern "C" unsigned long __cdecl _lrotr(unsigned long, int);
48 #pragma intrinsic(_lrotr)
52 #define VOGL_ROTATE_LEFT(x, k) _lrotl(x, k)
53 #define VOGL_ROTATE_RIGHT(x, k) _lrotr(x, k)
55 #define VOGL_ROTATE_LEFT(x, k) (((x) << (k)) | ((x) >> (32 - (k))))
56 #define VOGL_ROTATE_RIGHT(x, k) (((x) >> (k)) | ((x) << (32 - (k))))
59 template <class T, size_t N>
60 T decay_array_to_subtype(T (&a)[N]);
61 #define VOGL_ARRAY_SIZE(X) (sizeof(X) / sizeof(decay_array_to_subtype(X)))
63 #define VOGL_SIZEOF_U32(x) static_cast<uint32>(sizeof(x))
65 // Returns # of bits needed to encode x, i.e. 0=0, 1=1, 0xFFFF=15, 0x10000=16, etc.
66 #define VOGL_SIGNIFICANT_BITS(x) \
67 (!!((x) & 0x80000000) + !!((x) & 0xc0000000) + !!((x) & 0xe0000000) + !!((x) & 0xf0000000) + \
68 !!((x) & 0xf8000000) + !!((x) & 0xfc000000) + !!((x) & 0xfe000000) + !!((x) & 0xff000000) + \
69 !!((x) & 0xff800000) + !!((x) & 0xffc00000) + !!((x) & 0xffe00000) + !!((x) & 0xfff00000) + \
70 !!((x) & 0xfff80000) + !!((x) & 0xfffc0000) + !!((x) & 0xfffe0000) + !!((x) & 0xffff0000) + \
71 !!((x) & 0xffff8000) + !!((x) & 0xffffc000) + !!((x) & 0xffffe000) + !!((x) & 0xfffff000) + \
72 !!((x) & 0xfffff800) + !!((x) & 0xfffffc00) + !!((x) & 0xfffffe00) + !!((x) & 0xffffff00) + \
73 !!((x) & 0xffffff80) + !!((x) & 0xffffffc0) + !!((x) & 0xffffffe0) + !!((x) & 0xfffffff0) + \
74 !!((x) & 0xfffffff8) + !!((x) & 0xfffffffc) + !!((x) & 0xfffffffe) + !!((x) & 0xffffffff))
76 #define VOGL_HAS_NULLBYTE(x) (((x) - 0x01010101) & ~(x) & 0x80808080)
85 friend bool operator>(const T &a, const T &b)
89 friend bool operator<=(const T &a, const T &b)
93 friend bool operator>=(const T &a, const T &b)
97 friend bool operator!=(const T &a, const T &b)
103 // Given a less than comparison functor comp, compare a and b
104 template <typename T, typename F>
105 bool compare_lt(const T &a, const T &b, F comp)
109 template <typename T, typename F>
110 bool compare_le(const T &a, const T &b, F comp)
114 template <typename T, typename F>
115 bool compare_gt(const T &a, const T &b, F comp)
119 template <typename T, typename F>
120 bool compare_ge(const T &a, const T &b, F comp)
124 template <typename T, typename F>
125 bool compare_eq(const T &a, const T &b, F comp)
127 return !comp(a, b) && !comp(b, a);
129 template <typename T, typename F>
130 bool compare_neq(const T &a, const T &b, F comp)
132 return comp(a, b) || comp(b, a);
135 template <typename T>
136 inline void swap(T &l, T &r)
138 // Using std::swap() here now because it has C++0x optimizations and it can swap C-style arrays.
142 template <typename T>
143 inline void zero_object(T &obj)
145 memset((void *)&obj, 0, sizeof(obj));
148 template <typename T>
149 inline void zero_this(T *pObj)
151 memset((void *)pObj, 0, sizeof(*pObj));
154 inline bool is_bit_set(uint bits, uint mask)
156 return (bits & mask) != 0;
159 inline void set_bit(uint &bits, uint mask, bool state)
167 inline bool is_flag_set(uint bits, uint flag)
169 VOGL_ASSERT(flag < 32U);
170 return is_bit_set(bits, 1U << flag);
173 inline void set_flag(uint &bits, uint flag, bool state)
175 VOGL_ASSERT(flag < 32U);
176 set_bit(bits, 1U << flag, state);
179 inline void invert_buf(void *pBuf, uint size)
181 uint8 *p = static_cast<uint8 *>(pBuf);
183 const uint half_size = size >> 1;
184 for (uint i = 0; i < half_size; i++)
185 utils::swap(p[i], p[size - 1U - i]);
188 // buffer_is_little_endian is the endianness of the buffer's data
189 template <typename T>
190 inline void write_obj(const T &obj, void *pBuf, bool buffer_is_little_endian)
192 const uint8 *pSrc = reinterpret_cast<const uint8 *>(&obj);
193 uint8 *pDst = static_cast<uint8 *>(pBuf);
195 if (c_vogl_little_endian_platform == buffer_is_little_endian)
196 memcpy(pDst, pSrc, sizeof(T));
199 for (uint i = 0; i < sizeof(T); i++)
200 pDst[i] = pSrc[sizeof(T) - 1 - i];
204 // buffer_is_little_endian is the endianness of the buffer's data
205 template <typename T>
206 inline void read_obj(T &obj, const void *pBuf, bool buffer_is_little_endian)
208 const uint8 *pSrc = reinterpret_cast<const uint8 *>(pBuf);
209 uint8 *pDst = reinterpret_cast<uint8 *>(&obj);
211 if (c_vogl_little_endian_platform == buffer_is_little_endian)
212 memcpy(pDst, pSrc, sizeof(T));
215 for (uint i = 0; i < sizeof(T); i++)
216 pDst[i] = pSrc[sizeof(T) - 1 - i];
220 template <typename T>
221 inline bool write_obj(const T &obj, void *&pBuf, uint &buf_size, bool buffer_is_little_endian)
223 if (buf_size < sizeof(T))
226 utils::write_obj(obj, pBuf, buffer_is_little_endian);
228 pBuf = static_cast<uint8 *>(pBuf) + sizeof(T);
229 buf_size -= sizeof(T);
234 inline bool write_val(uint8 val, void *&pBuf, uint &buf_size, bool buffer_is_little_endian)
236 return write_obj(val, pBuf, buf_size, buffer_is_little_endian);
238 inline bool write_val(uint16 val, void *&pBuf, uint &buf_size, bool buffer_is_little_endian)
240 return write_obj(val, pBuf, buf_size, buffer_is_little_endian);
242 inline bool write_val(uint val, void *&pBuf, uint &buf_size, bool buffer_is_little_endian)
244 return write_obj(val, pBuf, buf_size, buffer_is_little_endian);
246 inline bool write_val(int val, void *&pBuf, uint &buf_size, bool buffer_is_little_endian)
248 return write_obj(val, pBuf, buf_size, buffer_is_little_endian);
250 inline bool write_val(uint64_t val, void *&pBuf, uint &buf_size, bool buffer_is_little_endian)
252 return write_obj(val, pBuf, buf_size, buffer_is_little_endian);
254 inline bool write_val(float val, void *&pBuf, uint &buf_size, bool buffer_is_little_endian)
256 return write_obj(val, pBuf, buf_size, buffer_is_little_endian);
258 inline bool write_val(double val, void *&pBuf, uint &buf_size, bool buffer_is_little_endian)
260 return write_obj(val, pBuf, buf_size, buffer_is_little_endian);
263 template <typename T>
264 inline bool read_obj(T &obj, const void *&pBuf, uint &buf_size, bool buffer_is_little_endian)
266 if (buf_size < sizeof(T))
272 utils::read_obj(obj, pBuf, buffer_is_little_endian);
274 pBuf = static_cast<const uint8 *>(pBuf) + sizeof(T);
275 buf_size -= sizeof(T);
280 #if defined(_MSC_VER)
281 VOGL_FORCE_INLINE uint16 swap16(uint16 x)
283 return _byteswap_ushort(x);
285 VOGL_FORCE_INLINE uint32 swap32(uint32 x)
287 return _byteswap_ulong(x);
289 VOGL_FORCE_INLINE uint64_t swap64(uint64_t x)
291 return _byteswap_uint64(x);
293 #elif defined(__GNUC__)
294 VOGL_FORCE_INLINE uint16 swap16(uint16 x)
296 return static_cast<uint16>((x << 8U) | (x >> 8U));
298 VOGL_FORCE_INLINE uint32 swap32(uint32 x)
300 return __builtin_bswap32(x);
302 VOGL_FORCE_INLINE uint64_t swap64(uint64_t x)
304 return __builtin_bswap64(x);
307 VOGL_FORCE_INLINE uint16 swap16(uint16 x)
309 return static_cast<uint16>((x << 8U) | (x >> 8U));
311 VOGL_FORCE_INLINE uint32 swap32(uint32 x)
313 return ((x << 24U) | ((x << 8U) & 0x00FF0000U) | ((x >> 8U) & 0x0000FF00U) | (x >> 24U));
315 VOGL_FORCE_INLINE uint64_t swap64(uint64_t x)
317 return (static_cast<uint64_t>(swap32(static_cast<uint32>(x))) << 32ULL) | swap32(static_cast<uint32>(x >> 32U));
321 // Assumes x has been read from memory as a little endian value, converts to native endianness for manipulation.
322 VOGL_FORCE_INLINE uint16 swap_le16_to_native(uint16 x)
324 return c_vogl_little_endian_platform ? x : swap16(x);
326 VOGL_FORCE_INLINE uint32 swap_le32_to_native(uint32 x)
328 return c_vogl_little_endian_platform ? x : swap32(x);
330 VOGL_FORCE_INLINE uint64_t swap_le64_to_native(uint64_t x)
332 return c_vogl_little_endian_platform ? x : swap64(x);
335 // Assumes x has been read from memory as a big endian value, converts to native endianness for manipulation.
336 VOGL_FORCE_INLINE uint16 swap_be16_to_native(uint16 x)
338 return c_vogl_big_endian_platform ? x : swap16(x);
340 VOGL_FORCE_INLINE uint32 swap_be32_to_native(uint32 x)
342 return c_vogl_big_endian_platform ? x : swap32(x);
344 VOGL_FORCE_INLINE uint64_t swap_be64_to_native(uint64_t x)
346 return c_vogl_big_endian_platform ? x : swap64(x);
349 VOGL_FORCE_INLINE uint32 read_le32(const void *p)
351 return swap_le32_to_native(*static_cast<const uint32 *>(p));
353 VOGL_FORCE_INLINE void write_le32(void *p, uint32 x)
355 *static_cast<uint32 *>(p) = swap_le32_to_native(x);
357 VOGL_FORCE_INLINE uint64_t read_le64(const void *p)
359 return swap_le64_to_native(*static_cast<const uint64_t *>(p));
361 VOGL_FORCE_INLINE void write_le64(void *p, uint64_t x)
363 *static_cast<uint64_t *>(p) = swap_le64_to_native(x);
366 VOGL_FORCE_INLINE uint32 read_be32(const void *p)
368 return swap_be32_to_native(*static_cast<const uint32 *>(p));
370 VOGL_FORCE_INLINE void write_be32(void *p, uint32 x)
372 *static_cast<uint32 *>(p) = swap_be32_to_native(x);
374 VOGL_FORCE_INLINE uint64_t read_be64(const void *p)
376 return swap_be64_to_native(*static_cast<const uint64_t *>(p));
378 VOGL_FORCE_INLINE void write_be64(void *p, uint64_t x)
380 *static_cast<uint64_t *>(p) = swap_be64_to_native(x);
383 inline void endian_swap_mem16(uint16 *p, uint n)
391 inline void endian_swap_mem32(uint32 *p, uint n)
399 inline void endian_swap_mem64(uint64_t *p, uint n)
408 inline void endian_swap_mem(void *p, uint size_in_bytes, uint type_size)
414 endian_swap_mem16(static_cast<uint16 *>(p), size_in_bytes / type_size);
418 endian_swap_mem32(static_cast<uint32 *>(p), size_in_bytes / type_size);
420 case sizeof(uint64_t)
422 endian_swap_mem64(static_cast<uint64_t *>(p), size_in_bytes / type_size);
427 inline void fast_memset(void *pDst, int val, size_t size)
429 memset(pDst, val, size);
432 inline void fast_memcpy(void *pDst, const void *pSrc, size_t size)
434 memcpy(pDst, pSrc, size);
437 inline uint count_leading_zeros(uint v)
483 inline uint count_leading_zeros16(uint v)
485 VOGL_ASSERT(v < 0x10000);
524 void endian_switch_words(uint16 *p, uint num);
525 void endian_switch_dwords(uint32 *p, uint num);
526 void copy_words(uint16 *pDst, const uint16 *pSrc, uint num, bool endian_switch);
527 void copy_dwords(uint32 *pDst, const uint32 *pSrc, uint num, bool endian_switch);
529 // Returns the maximum number of mip levels given the specified width/height, including the first (largest) mip level.
530 uint compute_max_mips(uint width, uint height, uint min_width = 1U, uint min_height = 1U);
531 uint compute_max_mips3D(uint width, uint height, uint depth, uint min_width = 1U, uint min_height = 1U, uint min_depth = 1U);
533 bool check_for_sse_4_1_support();
535 inline char to_hex(uint v)
537 VOGL_ASSERT(v <= 0xF);
545 inline int from_hex(char c)
547 if ((c >= '0') && (c <= '9'))
549 else if ((c >= 'a') && (c <= 'f'))
550 return (c - 'a') + 10;
551 else if ((c >= 'A') && (c <= 'F'))
552 return (c - 'A') + 10;
556 bool is_buffer_printable(const void *pBuf, uint buf_size, bool include_crlf, bool expect_null_terminator);
558 extern const int64_t s_signed_mins[9];
559 extern const int64_t s_signed_maxs[9];
560 extern const uint64_t s_unsigned_maxes[9];
562 inline int64_t get_signed_min_value(uint integral_type_size)
564 VOGL_ASSERT(integral_type_size <= 8);
565 int64_t val = (integral_type_size <= 8) ? s_signed_mins[integral_type_size] : 0;
566 VOGL_ASSERT((!integral_type_size) || (val == (-s_signed_maxs[integral_type_size] - 1)));
570 inline int64_t get_signed_max_value(uint integral_type_size)
572 VOGL_ASSERT(integral_type_size <= 8);
573 int64_t val = (integral_type_size <= 8) ? s_signed_maxs[integral_type_size] : 0;
574 VOGL_ASSERT((!integral_type_size) || (val == -(s_signed_mins[integral_type_size] + 1)));
578 inline uint64_t get_unsigned_max_value(uint integral_type_size)
580 VOGL_ASSERT(integral_type_size <= 8);
581 uint64_t val = (integral_type_size <= 8) ? s_unsigned_maxes[integral_type_size] : 0;
582 VOGL_ASSERT((integral_type_size == 8) ? (val == cUINT64_MAX) : (val == ((1ULL << (integral_type_size * 8U)) - 1ULL)));
583 uint64_t k = (static_cast<uint64_t>(1ULL | (s_signed_maxs[integral_type_size]) << 1U));
585 VOGL_ASSERT((!integral_type_size) || (val == k));
589 inline bool is_8bit(uint64_t val)
591 return val <= cUINT8_MAX;
594 inline bool is_8bit(int64_t val)
596 return (val >= cINT8_MIN) && (val <= cINT8_MAX);
599 inline bool is_16bit(uint64_t val)
601 return val <= cUINT16_MAX;
604 inline bool is_16bit(int64_t val)
606 return (val >= cINT16_MIN) && (val <= cINT16_MAX);
609 inline bool is_32bit(uint64_t val)
611 return val <= cUINT32_MAX;
614 inline bool is_32bit(int64_t val)
616 return (val >= cINT32_MIN) && (val <= cINT32_MAX);
619 // map_value: attempts to map the specified value from F to T, or returns def_value if the map isn't possible
621 template <typename V, typename F, typename T>
622 inline T map_value(V value, T def_value, F f0, T t0)
629 template <typename V, typename F, typename T>
630 inline T map_value(V value, T def_value, F f0, T t0, F f1, T t1)
634 else if (value == f1)
639 template <typename V, typename F, typename T>
640 inline T map_value(V value, T def_value, F f0, T t0, F f1, T t1, F f2, T t2)
644 else if (value == f1)
646 else if (value == f2)
651 template <typename V, typename F, typename T>
652 inline T map_value(V value, T def_value, F f0, T t0, F f1, T t1, F f2, T t2, F f3, T t3)
656 else if (value == f1)
658 else if (value == f2)
660 else if (value == f3)
665 template <typename V, typename F, typename T>
666 inline T map_value(V value, T def_value, F f0, T t0, F f1, T t1, F f2, T t2, F f3, T t3, F f4, T t4)
670 else if (value == f1)
672 else if (value == f2)
674 else if (value == f3)
676 else if (value == f4)
681 template <typename V, typename F, typename T>
682 inline T map_value(V value, T def_value, F f0, T t0, F f1, T t1, F f2, T t2, F f3, T t3, F f4, T t4, F f5, T t5)
686 else if (value == f1)
688 else if (value == f2)
690 else if (value == f3)
692 else if (value == f4)
694 else if (value == f5)
699 template <typename V, typename F, typename T>
700 inline T map_value(V value, T def_value, F f0, T t0, F f1, T t1, F f2, T t2, F f3, T t3, F f4, T t4, F f5, T t5, F f6, T t6)
704 else if (value == f1)
706 else if (value == f2)
708 else if (value == f3)
710 else if (value == f4)
712 else if (value == f5)
714 else if (value == f6)
719 template <typename V, typename F, typename T>
720 inline T map_value(V value, T def_value, F f0, T t0, F f1, T t1, F f2, T t2, F f3, T t3, F f4, T t4, F f5, T t5, F f6, T t6, F f7, T t7)
724 else if (value == f1)
726 else if (value == f2)
728 else if (value == f3)
730 else if (value == f4)
732 else if (value == f5)
734 else if (value == f6)
736 else if (value == f7)
741 template <typename V, typename F, typename T>
742 inline T map_value(V value, T def_value, F f0, T t0, F f1, T t1, F f2, T t2, F f3, T t3, F f4, T t4, F f5, T t5, F f6, T t6, F f7, T t7, F f8, T t8)
746 else if (value == f1)
748 else if (value == f2)
750 else if (value == f3)
752 else if (value == f4)
754 else if (value == f5)
756 else if (value == f6)
758 else if (value == f7)
760 else if (value == f8)
765 template <typename V, typename F, typename T>
766 inline T map_value(V value, T def_value, F f0, T t0, F f1, T t1, F f2, T t2, F f3, T t3, F f4, T t4, F f5, T t5, F f6, T t6, F f7, T t7, F f8, T t8, F f9, T t9)
770 else if (value == f1)
772 else if (value == f2)
774 else if (value == f3)
776 else if (value == f4)
778 else if (value == f5)
780 else if (value == f6)
782 else if (value == f7)
784 else if (value == f8)
786 else if (value == f9)
791 template <typename V, typename F, typename T>
792 inline T map_value(V value, T def_value, F f0, T t0, F f1, T t1, F f2, T t2, F f3, T t3, F f4, T t4, F f5, T t5, F f6, T t6, F f7, T t7, F f8, T t8, F f9, T t9, F f10, T t10)
796 else if (value == f1)
798 else if (value == f2)
800 else if (value == f3)
802 else if (value == f4)
804 else if (value == f5)
806 else if (value == f6)
808 else if (value == f7)
810 else if (value == f8)
812 else if (value == f9)
814 else if (value == f10)
819 // is_in_set: true if value is either v0, v1, etc.
821 template <typename V, typename T>
822 inline bool is_in_set(V value, T v0)
827 template <typename V, typename T>
828 inline bool is_in_set(V value, T v0, T v1)
830 return (value == v0) || (value == v1);
833 template <typename V, typename T>
834 inline bool is_in_set(V value, T v0, T v1, T v2)
836 return (value == v0) || (value == v1) || (value == v2);
839 template <typename V, typename T>
840 inline bool is_in_set(V value, T v0, T v1, T v2, T v3)
842 return (value == v0) || (value == v1) || (value == v2) || (value == v3);
845 template <typename V, typename T>
846 inline bool is_in_set(V value, T v0, T v1, T v2, T v3, T v4)
848 return (value == v0) || (value == v1) || (value == v2) || (value == v3) || (value == v4);
851 template <typename V, typename T>
852 inline bool is_in_set(V value, T v0, T v1, T v2, T v3, T v4, T v5)
854 return (value == v0) || (value == v1) || (value == v2) || (value == v3) || (value == v4) || (value == v5);
857 template <typename V, typename T>
858 inline bool is_in_set(V value, T v0, T v1, T v2, T v3, T v4, T v5, T v6)
860 return (value == v0) || (value == v1) || (value == v2) || (value == v3) || (value == v4) || (value == v5) || (value == v6);
863 template <typename V, typename T>
864 inline bool is_in_set(V value, T v0, T v1, T v2, T v3, T v4, T v5, T v6, T v7)
866 return (value == v0) || (value == v1) || (value == v2) || (value == v3) || (value == v4) || (value == v5) || (value == v6) || (value == v7);
869 template <typename V, typename T>
870 inline bool is_in_set(V value, T v0, T v1, T v2, T v3, T v4, T v5, T v6, T v7, T v8)
872 return (value == v0) || (value == v1) || (value == v2) || (value == v3) || (value == v4) || (value == v5) || (value == v6) || (value == v7) || (value == v8);
875 template <typename V, typename T>
876 inline bool is_in_set(V value, T v0, T v1, T v2, T v3, T v4, T v5, T v6, T v7, T v8, T v9)
878 return (value == v0) || (value == v1) || (value == v2) || (value == v3) || (value == v4) || (value == v5) || (value == v6) || (value == v7) || (value == v8) || (value == v9);
881 template <typename V, typename T>
882 inline bool is_in_set(V value, T v0, T v1, T v2, T v3, T v4, T v5, T v6, T v7, T v8, T v9, T v10)
884 return (value == v0) || (value == v1) || (value == v2) || (value == v3) || (value == v4) || (value == v5) || (value == v6) || (value == v7) || (value == v8) || (value == v9) || (value == v10);
887 template <typename V, typename T>
888 inline bool is_in_set(V value, T v0, T v1, T v2, T v3, T v4, T v5, T v6, T v7, T v8, T v9, T v10, T v11)
890 return (value == v0) || (value == v1) || (value == v2) || (value == v3) || (value == v4) || (value == v5) || (value == v6) || (value == v7) || (value == v8) || (value == v9) || (value == v10) || (value == v11);
893 // is_not_in_set: true if value is != v0, and != v1, etc.
895 template <typename V, typename T>
896 inline bool is_not_in_set(V value, T v0)
901 template <typename V, typename T>
902 inline bool is_not_in_set(V value, T v0, T v1)
904 return (value != v0) && (value != v1);
907 template <typename V, typename T>
908 inline bool is_not_in_set(V value, T v0, T v1, T v2)
910 return (value != v0) && (value != v1) && (value != v2);
913 template <typename V, typename T>
914 inline bool is_not_in_set(V value, T v0, T v1, T v2, T v3)
916 return (value != v0) && (value != v1) && (value != v2) && (value != v3);
919 template <typename V, typename T>
920 inline bool is_not_in_set(V value, T v0, T v1, T v2, T v3, T v4)
922 return (value != v0) && (value != v1) && (value != v2) && (value != v3) && (value != v4);
925 template <typename V, typename T>
926 inline bool is_not_in_set(V value, T v0, T v1, T v2, T v3, T v4, T v5)
928 return (value != v0) && (value != v1) && (value != v2) && (value != v3) && (value != v4) && (value != v5);
931 template <typename V, typename T>
932 inline bool is_not_in_set(V value, T v0, T v1, T v2, T v3, T v4, T v5, T v6)
934 return (value != v0) && (value != v1) && (value != v2) && (value != v3) && (value != v4) && (value != v5) && (value != v6);
937 template <typename V, typename T>
938 inline bool is_not_in_set(V value, T v0, T v1, T v2, T v3, T v4, T v5, T v6, T v7)
940 return (value != v0) && (value != v1) && (value != v2) && (value != v3) && (value != v4) && (value != v5) && (value != v6) && (value != v7);
943 template <typename V, typename T>
944 inline bool is_not_in_set(V value, T v0, T v1, T v2, T v3, T v4, T v5, T v6, T v7, T v8)
946 return (value != v0) && (value != v1) && (value != v2) && (value != v3) && (value != v4) && (value != v5) && (value != v6) && (value != v7) && (value != v8);
949 // map_to_index: tries to map value v0, v1, and returns its index, or returns def
951 template <typename V, typename T>
952 inline int map_to_index(V value, int def, T v0)
959 template <typename V, typename T>
960 inline int map_to_index(V value, int def, T v0, T v1)
964 else if (value == v1)
969 template <typename V, typename T>
970 inline int map_to_index(V value, int def, T v0, T v1, T v2)
974 else if (value == v1)
976 else if (value == v2)
981 template <typename V, typename T>
982 inline int map_to_index(V value, int def, T v0, T v1, T v2, T v3)
986 else if (value == v1)
988 else if (value == v2)
990 else if (value == v3)
995 template <typename V, typename T>
996 inline int map_to_index(V value, int def, T v0, T v1, T v2, T v3, T v4)
1000 else if (value == v1)
1002 else if (value == v2)
1004 else if (value == v3)
1006 else if (value == v4)
1011 template <typename V, typename T>
1012 inline int map_to_index(V value, int def, T v0, T v1, T v2, T v3, T v4, T v5)
1016 else if (value == v1)
1018 else if (value == v2)
1020 else if (value == v3)
1022 else if (value == v4)
1024 else if (value == v5)
1029 template <typename V, typename T>
1030 inline int map_to_index(V value, int def, T v0, T v1, T v2, T v3, T v4, T v5, T v6)
1034 else if (value == v1)
1036 else if (value == v2)
1038 else if (value == v3)
1040 else if (value == v4)
1042 else if (value == v5)
1044 else if (value == v6)
1049 template <typename V, typename T>
1050 inline int map_to_index(V value, int def, T v0, T v1, T v2, T v3, T v4, T v5, T v6, T v7)
1054 else if (value == v1)
1056 else if (value == v2)
1058 else if (value == v3)
1060 else if (value == v4)
1062 else if (value == v5)
1064 else if (value == v6)
1066 else if (value == v7)
1071 template <typename V, typename T>
1072 inline int map_to_index(V value, int def, T v0, T v1, T v2, T v3, T v4, T v5, T v6, T v7, T v8)
1076 else if (value == v1)
1078 else if (value == v2)
1080 else if (value == v3)
1082 else if (value == v4)
1084 else if (value == v5)
1086 else if (value == v6)
1088 else if (value == v7)
1090 else if (value == v8)
1095 // Finds value in the specified static array, or -1 if it can't be found
1096 template <typename V, typename T, size_t size>
1097 inline int64_t find_value_in_array(V value, T (&p)[size])
1099 for (size_t i = 0; i < size; i++)
1105 // Finds value in the specified array, or -1 if it can't be found
1106 template <typename V, typename T>
1107 inline int64_t find_value_in_array(V value, T *p, size_t size)
1109 for (size_t i = 0; i < size; i++)
1115 // Should be called before using RDTSC().
1118 inline uint64_t get_rdtsc()
1120 #if defined(__GNUC__)
1121 unsigned int hi, lo;
1122 __asm__ volatile("rdtsc" : "=a"(lo), "=d"(hi));
1123 return ((uint64_t)hi << 32) | lo;
1129 inline uint64_t RDTSC()
1131 #if defined(VOGL_USE_LINUX_API)
1132 extern int g_reliable_rdtsc;
1133 if (g_reliable_rdtsc == -1)
1135 if (g_reliable_rdtsc == 0)
1137 //$ TODO: Should just use SDL_GetPerformanceCounter?
1138 struct timespec time;
1139 clock_gettime(CLOCK_MONOTONIC, &time);
1140 return ((uint64_t)time.tv_sec * 1000000000) + time.tv_nsec;
1146 } // namespace utils