summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/bx
diff options
context:
space:
mode:
author Branimir Karadžić <branimirkaradzic@gmail.com>2017-02-05 13:56:35 +0100
committer Miodrag Milanovic <mmicko@gmail.com>2017-02-05 13:56:35 +0100
commit1607745432f50099711d7aee355111111e66ff51 (patch)
treec4eaec8008f6e0283ca652cdffb55a34eca9b9bb /3rdparty/bx
parent193e8c8a89a4be5c63909cdbbcca4d9d6f8fee02 (diff)
Update BGFX and BX (nw)
Diffstat (limited to '3rdparty/bx')
-rw-r--r--3rdparty/bx/include/bx/allocator.h158
-rw-r--r--3rdparty/bx/include/bx/allocator.inl104
-rw-r--r--3rdparty/bx/include/bx/bx.h42
-rw-r--r--3rdparty/bx/include/bx/commandline.h233
-rw-r--r--3rdparty/bx/include/bx/crtimpl.h416
-rw-r--r--3rdparty/bx/include/bx/debug.h71
-rw-r--r--3rdparty/bx/include/bx/easing.h289
-rw-r--r--3rdparty/bx/include/bx/easing.inl256
-rw-r--r--3rdparty/bx/include/bx/endian.h73
-rw-r--r--3rdparty/bx/include/bx/endian.inl78
-rw-r--r--3rdparty/bx/include/bx/error.h87
-rw-r--r--3rdparty/bx/include/bx/error.inl73
-rw-r--r--3rdparty/bx/include/bx/foreach.h71
-rw-r--r--3rdparty/bx/include/bx/fpumath.h1580
-rw-r--r--3rdparty/bx/include/bx/fpumath.inl1416
-rw-r--r--3rdparty/bx/include/bx/handlealloc.h719
-rw-r--r--3rdparty/bx/include/bx/handlealloc.inl712
-rw-r--r--3rdparty/bx/include/bx/hash.h162
-rw-r--r--3rdparty/bx/include/bx/hash.inl154
-rw-r--r--3rdparty/bx/include/bx/mutex.h120
-rw-r--r--3rdparty/bx/include/bx/mutex.inl34
-rw-r--r--3rdparty/bx/include/bx/os.h362
-rw-r--r--3rdparty/bx/include/bx/pixelformat.h243
-rw-r--r--3rdparty/bx/include/bx/pixelformat.inl945
-rw-r--r--3rdparty/bx/include/bx/platform.h67
-rw-r--r--3rdparty/bx/include/bx/process.h80
-rw-r--r--3rdparty/bx/include/bx/radixsort.h306
-rw-r--r--3rdparty/bx/include/bx/radixsort.inl288
-rw-r--r--3rdparty/bx/include/bx/readerwriter.h565
-rw-r--r--3rdparty/bx/include/bx/readerwriter.inl452
-rw-r--r--3rdparty/bx/include/bx/rng.h178
-rw-r--r--3rdparty/bx/include/bx/rng.inl171
-rw-r--r--3rdparty/bx/include/bx/sem.h233
-rw-r--r--3rdparty/bx/include/bx/simd256_avx.inl6
-rw-r--r--3rdparty/bx/include/bx/string.h756
-rw-r--r--3rdparty/bx/include/bx/string.inl200
-rw-r--r--3rdparty/bx/include/bx/thread.h270
-rw-r--r--3rdparty/bx/include/bx/thread.inl65
-rw-r--r--3rdparty/bx/include/bx/timer.h51
-rw-r--r--3rdparty/bx/include/bx/timer.inl61
-rw-r--r--3rdparty/bx/include/bx/tokenizecmd.h146
-rw-r--r--3rdparty/bx/include/bx/uint32_t.h971
-rw-r--r--3rdparty/bx/include/bx/uint32_t.inl781
-rw-r--r--3rdparty/bx/makefile4
-rw-r--r--3rdparty/bx/scripts/bin2c.lua4
-rw-r--r--3rdparty/bx/scripts/bx.lua25
-rw-r--r--3rdparty/bx/scripts/genie.lua8
-rw-r--r--3rdparty/bx/scripts/toolchain.lua16
-rw-r--r--3rdparty/bx/src/commandline.cpp322
-rw-r--r--3rdparty/bx/src/crt.cpp362
-rw-r--r--3rdparty/bx/src/crtimpl.cpp360
-rw-r--r--3rdparty/bx/src/debug.cpp143
-rw-r--r--3rdparty/bx/src/dtoa.cpp528
-rw-r--r--3rdparty/bx/src/fpumath.cpp100
-rw-r--r--3rdparty/bx/src/mutex.cpp92
-rw-r--r--3rdparty/bx/src/os.cpp454
-rw-r--r--3rdparty/bx/src/sem.cpp221
-rw-r--r--3rdparty/bx/src/string.cpp515
-rw-r--r--3rdparty/bx/src/thread.cpp208
-rw-r--r--3rdparty/bx/tests/dbg.cpp87
-rw-r--r--3rdparty/bx/tests/dbg.h9
-rw-r--r--3rdparty/bx/tests/fpumath_test.cpp22
-rw-r--r--3rdparty/bx/tests/handle_bench.cpp12
-rw-r--r--3rdparty/bx/tests/misc_test.cpp8
-rw-r--r--3rdparty/bx/tests/os_test.cpp20
-rw-r--r--3rdparty/bx/tests/string_test.cpp136
-rw-r--r--3rdparty/bx/tests/test.h4
-rw-r--r--3rdparty/bx/tests/tokenizecmd_test.cpp4
-rw-r--r--3rdparty/bx/tests/uint32_test.cpp65
-rw-r--r--3rdparty/bx/tests/vector_complex_test.cpp6
-rw-r--r--3rdparty/bx/tests/vsnprintf_test.cpp68
-rwxr-xr-x3rdparty/bx/tools/bin/darwin/geniebin524544 -> 524544 bytes
-rwxr-xr-x3rdparty/bx/tools/bin/linux/geniebin503472 -> 503472 bytes
-rw-r--r--3rdparty/bx/tools/bin/windows/genie.exebin507904 -> 508416 bytes
74 files changed, 11283 insertions, 6565 deletions
diff --git a/3rdparty/bx/include/bx/allocator.h b/3rdparty/bx/include/bx/allocator.h
index f74b78b2c59..a1ab3e30826 100644
--- a/3rdparty/bx/include/bx/allocator.h
+++ b/3rdparty/bx/include/bx/allocator.h
@@ -8,7 +8,6 @@
#include "bx.h"
-#include <memory.h>
#include <string.h> //::memmove
#include <new>
@@ -42,18 +41,6 @@
namespace bx
{
- /// Aligns pointer to nearest next aligned address. _align must be power of two.
- inline void* alignPtr(void* _ptr, size_t _extra, size_t _align = BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT)
- {
- union { void* ptr; size_t addr; } un;
- un.ptr = _ptr;
- size_t unaligned = un.addr + _extra; // space for header
- size_t mask = _align-1;
- size_t aligned = BX_ALIGN_MASK(unaligned, mask);
- un.addr = aligned;
- return un.ptr;
- }
-
struct BX_NO_VTABLE AllocatorI
{
virtual ~AllocatorI() = 0;
@@ -68,79 +55,84 @@ namespace bx
virtual void* realloc(void* _ptr, size_t _size, size_t _align, const char* _file, uint32_t _line) = 0;
};
- inline AllocatorI::~AllocatorI()
- {
- }
-
- inline void* alloc(AllocatorI* _allocator, size_t _size, size_t _align = 0, const char* _file = NULL, uint32_t _line = 0)
- {
- return _allocator->realloc(NULL, _size, _align, _file, _line);
- }
-
- inline void free(AllocatorI* _allocator, void* _ptr, size_t _align = 0, const char* _file = NULL, uint32_t _line = 0)
- {
- _allocator->realloc(_ptr, 0, _align, _file, _line);
- }
-
- inline void* realloc(AllocatorI* _allocator, void* _ptr, size_t _size, size_t _align = 0, const char* _file = NULL, uint32_t _line = 0)
- {
- return _allocator->realloc(_ptr, _size, _align, _file, _line);
- }
-
- static inline void* alignedAlloc(AllocatorI* _allocator, size_t _size, size_t _align, const char* _file = NULL, uint32_t _line = 0)
- {
- size_t total = _size + _align;
- uint8_t* ptr = (uint8_t*)alloc(_allocator, total, 0, _file, _line);
- uint8_t* aligned = (uint8_t*)alignPtr(ptr, sizeof(uint32_t), _align);
- uint32_t* header = (uint32_t*)aligned - 1;
- *header = uint32_t(aligned - ptr);
- return aligned;
- }
-
- static inline void alignedFree(AllocatorI* _allocator, void* _ptr, size_t /*_align*/, const char* _file = NULL, uint32_t _line = 0)
- {
- uint8_t* aligned = (uint8_t*)_ptr;
- uint32_t* header = (uint32_t*)aligned - 1;
- uint8_t* ptr = aligned - *header;
- free(_allocator, ptr, 0, _file, _line);
- }
-
- static inline void* alignedRealloc(AllocatorI* _allocator, void* _ptr, size_t _size, size_t _align, const char* _file = NULL, uint32_t _line = 0)
- {
- if (NULL == _ptr)
- {
- return alignedAlloc(_allocator, _size, _align, _file, _line);
- }
-
- uint8_t* aligned = (uint8_t*)_ptr;
- uint32_t offset = *( (uint32_t*)aligned - 1);
- uint8_t* ptr = aligned - offset;
- size_t total = _size + _align;
- ptr = (uint8_t*)realloc(_allocator, ptr, total, 0, _file, _line);
- uint8_t* newAligned = (uint8_t*)alignPtr(ptr, sizeof(uint32_t), _align);
-
- if (newAligned == aligned)
- {
- return aligned;
- }
-
- aligned = ptr + offset;
- ::memmove(newAligned, aligned, _size);
- uint32_t* header = (uint32_t*)newAligned - 1;
- *header = uint32_t(newAligned - ptr);
- return newAligned;
- }
+ /// Check if pointer is aligned. _align must be power of two.
+ bool isAligned(const void* _ptr, size_t _align);
+ /// Aligns pointer to nearest next aligned address. _align must be power of two.
+ void* alignPtr(
+ void* _ptr
+ , size_t _extra
+ , size_t _align = BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT
+ );
+
+ ///
+ void* alloc(
+ AllocatorI* _allocator
+ , size_t _size
+ , size_t _align = 0
+ , const char* _file = NULL
+ , uint32_t _line = 0
+ );
+
+ ///
+ void free(
+ AllocatorI* _allocator
+ , void* _ptr
+ , size_t _align = 0
+ , const char* _file = NULL
+ , uint32_t _line = 0
+ );
+
+ ///
+ void* realloc(
+ AllocatorI* _allocator
+ , void* _ptr
+ , size_t _size
+ , size_t _align = 0
+ , const char* _file = NULL
+ , uint32_t _line = 0
+ );
+
+ ///
+ void* alignedAlloc(
+ AllocatorI* _allocator
+ , size_t _size
+ , size_t _align
+ , const char* _file = NULL
+ , uint32_t _line = 0
+ );
+
+ ///
+ void alignedFree(
+ AllocatorI* _allocator
+ , void* _ptr
+ , size_t /*_align*/
+ , const char* _file = NULL
+ , uint32_t _line = 0
+ );
+
+ ///
+ void* alignedRealloc(
+ AllocatorI* _allocator
+ , void* _ptr
+ , size_t _size
+ , size_t _align
+ , const char* _file = NULL
+ , uint32_t _line = 0
+ );
+
+ ///
template <typename ObjectT>
- inline void deleteObject(AllocatorI* _allocator, ObjectT* _object, size_t _align = 0, const char* _file = NULL, uint32_t _line = 0)
- {
- if (NULL != _object)
- {
- _object->~ObjectT();
- free(_allocator, _object, _align, _file, _line);
- }
- }
+ void deleteObject(
+ AllocatorI* _allocator
+ , ObjectT* _object
+ , size_t _align = 0
+ , const char* _file = NULL
+ , uint32_t _line = 0
+ );
} // namespace bx
+#include "allocator.inl"
+
#endif // BX_ALLOCATOR_H_HEADER_GUARD
diff --git a/3rdparty/bx/include/bx/allocator.inl b/3rdparty/bx/include/bx/allocator.inl
new file mode 100644
index 00000000000..67a4a5325c5
--- /dev/null
+++ b/3rdparty/bx/include/bx/allocator.inl
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2010-2017 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ */
+
+#ifndef BX_ALLOCATOR_H_HEADER_GUARD
+# error "Must be included from bx/allocator.h"
+#endif // BX_ALLOCATOR_H_HEADER_GUARD
+
+namespace bx
+{
+ inline AllocatorI::~AllocatorI()
+ {
+ }
+
+ inline bool isAligned(const void* _ptr, size_t _align)
+ {
+ union { const void* ptr; uintptr_t addr; } un;
+ un.ptr = _ptr;
+ return 0 == (un.addr & (_align-1) );
+ }
+
+ inline void* alignPtr(void* _ptr, size_t _extra, size_t _align)
+ {
+ union { void* ptr; uintptr_t addr; } un;
+ un.ptr = _ptr;
+ uintptr_t unaligned = un.addr + _extra; // space for header
+ uintptr_t mask = _align-1;
+ uintptr_t aligned = BX_ALIGN_MASK(unaligned, mask);
+ un.addr = aligned;
+ return un.ptr;
+ }
+
+ inline void* alloc(AllocatorI* _allocator, size_t _size, size_t _align, const char* _file, uint32_t _line)
+ {
+ return _allocator->realloc(NULL, _size, _align, _file, _line);
+ }
+
+ inline void free(AllocatorI* _allocator, void* _ptr, size_t _align, const char* _file, uint32_t _line)
+ {
+ _allocator->realloc(_ptr, 0, _align, _file, _line);
+ }
+
+ inline void* realloc(AllocatorI* _allocator, void* _ptr, size_t _size, size_t _align, const char* _file, uint32_t _line)
+ {
+ return _allocator->realloc(_ptr, _size, _align, _file, _line);
+ }
+
+ inline void* alignedAlloc(AllocatorI* _allocator, size_t _size, size_t _align, const char* _file, uint32_t _line)
+ {
+ size_t total = _size + _align;
+ uint8_t* ptr = (uint8_t*)alloc(_allocator, total, 0, _file, _line);
+ uint8_t* aligned = (uint8_t*)alignPtr(ptr, sizeof(uint32_t), _align);
+ uint32_t* header = (uint32_t*)aligned - 1;
+ *header = uint32_t(aligned - ptr);
+ return aligned;
+ }
+
+ inline void alignedFree(AllocatorI* _allocator, void* _ptr, size_t _align, const char* _file, uint32_t _line)
+ {
+ BX_UNUSED(_align);
+ uint8_t* aligned = (uint8_t*)_ptr;
+ uint32_t* header = (uint32_t*)aligned - 1;
+ uint8_t* ptr = aligned - *header;
+ free(_allocator, ptr, 0, _file, _line);
+ }
+
+ inline void* alignedRealloc(AllocatorI* _allocator, void* _ptr, size_t _size, size_t _align, const char* _file, uint32_t _line)
+ {
+ if (NULL == _ptr)
+ {
+ return alignedAlloc(_allocator, _size, _align, _file, _line);
+ }
+
+ uint8_t* aligned = (uint8_t*)_ptr;
+ uint32_t offset = *( (uint32_t*)aligned - 1);
+ uint8_t* ptr = aligned - offset;
+ size_t total = _size + _align;
+ ptr = (uint8_t*)realloc(_allocator, ptr, total, 0, _file, _line);
+ uint8_t* newAligned = (uint8_t*)alignPtr(ptr, sizeof(uint32_t), _align);
+
+ if (newAligned == aligned)
+ {
+ return aligned;
+ }
+
+ aligned = ptr + offset;
+ ::memmove(newAligned, aligned, _size);
+ uint32_t* header = (uint32_t*)newAligned - 1;
+ *header = uint32_t(newAligned - ptr);
+ return newAligned;
+ }
+
+ template <typename ObjectT>
+ inline void deleteObject(AllocatorI* _allocator, ObjectT* _object, size_t _align, const char* _file, uint32_t _line)
+ {
+ if (NULL != _object)
+ {
+ _object->~ObjectT();
+ free(_allocator, _object, _align, _file, _line);
+ }
+ }
+
+} // namespace bx
diff --git a/3rdparty/bx/include/bx/bx.h b/3rdparty/bx/include/bx/bx.h
index 65a50d08cb4..43ccba3cce1 100644
--- a/3rdparty/bx/include/bx/bx.h
+++ b/3rdparty/bx/include/bx/bx.h
@@ -8,7 +8,7 @@
#include <stdint.h> // uint32_t
#include <stdlib.h> // size_t
-#include <string.h> // memcpy
+#include <stddef.h> // ptrdiff_t
#include "config.h"
#include "macros.h"
@@ -45,39 +45,23 @@ namespace bx
Ty tmp = _a; _a = _b; _b = tmp;
}
- /// Check if pointer is aligned. _align must be power of two.
- inline bool isPtrAligned(const void* _ptr, size_t _align)
- {
- union { const void* ptr; size_t addr; } un;
- un.ptr = _ptr;
- return 0 == (un.addr & (_align-1) );
- }
+ ///
+ void* memCopy(void* _dst, const void* _src, size_t _numBytes);
- /// Scatter/gather memcpy.
- inline void memCopy(void* _dst, const void* _src, uint32_t _size, uint32_t _num, uint32_t _srcPitch, uint32_t _dstPitch)
- {
- const uint8_t* src = (const uint8_t*)_src;
- uint8_t* dst = (uint8_t*)_dst;
-
- for (uint32_t ii = 0; ii < _num; ++ii)
- {
- memcpy(dst, src, _size);
- src += _srcPitch;
- dst += _dstPitch;
- }
- }
+ ///
+ void memCopy(void* _dst, const void* _src, uint32_t _size, uint32_t _num, uint32_t _srcPitch, uint32_t _dstPitch);
///
- inline void gather(void* _dst, const void* _src, uint32_t _size, uint32_t _num, uint32_t _srcPitch)
- {
- memCopy(_dst, _src, _size, _num, _srcPitch, _size);
- }
+ void gather(void* _dst, const void* _src, uint32_t _size, uint32_t _num, uint32_t _srcPitch);
///
- inline void scatter(void* _dst, const void* _src, uint32_t _size, uint32_t _num, uint32_t _dstPitch)
- {
- memCopy(_dst, _src, _size, _num, _size, _dstPitch);
- }
+ void scatter(void* _dst, const void* _src, uint32_t _size, uint32_t _num, uint32_t _dstPitch);
+
+ ///
+ void* memMove(void* _dst, const void* _src, size_t _numBytes);
+
+ ///
+ void* memSet(void* _dst, uint8_t _ch, size_t _numBytes);
} // namespace bx
diff --git a/3rdparty/bx/include/bx/commandline.h b/3rdparty/bx/include/bx/commandline.h
index bafd48e3be2..9b9a397360b 100644
--- a/3rdparty/bx/include/bx/commandline.h
+++ b/3rdparty/bx/include/bx/commandline.h
@@ -7,197 +7,64 @@
#define BX_COMMANDLINE_H_HEADER_GUARD
#include "bx.h"
-#include "string.h"
namespace bx
{
+ /// Reference:
+ /// http://msdn.microsoft.com/en-us/library/a1y7w461.aspx
+ const char* tokenizeCommandLine(const char* _commandLine, char* _buffer, uint32_t& _bufferSize, int32_t& _argc, char* _argv[], int32_t _maxArgvs, char _term = '\0');
+
+ ///
class CommandLine
{
public:
- CommandLine(int _argc, char const* const* _argv)
- : m_argc(_argc)
- , m_argv(_argv)
- {
- }
-
- const char* findOption(const char* _long, const char* _default) const
- {
- const char* result = find(0, '\0', _long, 1);
- return result == NULL ? _default : result;
- }
-
- const char* findOption(const char _short, const char* _long, const char* _default) const
- {
- const char* result = find(0, _short, _long, 1);
- return result == NULL ? _default : result;
- }
-
- const char* findOption(const char* _long, int _numParams = 1) const
- {
- const char* result = find(0, '\0', _long, _numParams);
- return result;
- }
-
- const char* findOption(const char _short, const char* _long = NULL, int _numParams = 1) const
- {
- const char* result = find(0, _short, _long, _numParams);
- return result;
- }
-
- const char* findOption(int _skip, const char _short, const char* _long = NULL, int _numParams = 1) const
- {
- const char* result = find(_skip, _short, _long, _numParams);
- return result;
- }
-
- bool hasArg(const char _short, const char* _long = NULL) const
- {
- const char* arg = findOption(_short, _long, 0);
- return NULL != arg;
- }
-
- bool hasArg(const char* _long) const
- {
- const char* arg = findOption('\0', _long, 0);
- return NULL != arg;
- }
-
- bool hasArg(const char*& _value, const char _short, const char* _long = NULL) const
- {
- const char* arg = findOption(_short, _long, 1);
- _value = arg;
- return NULL != arg;
- }
-
- bool hasArg(int& _value, const char _short, const char* _long = NULL) const
- {
- const char* arg = findOption(_short, _long, 1);
- if (NULL != arg)
- {
- _value = atoi(arg);
- return true;
- }
-
- return false;
- }
-
- bool hasArg(unsigned int& _value, const char _short, const char* _long = NULL) const
- {
- const char* arg = findOption(_short, _long, 1);
- if (NULL != arg)
- {
- _value = atoi(arg);
- return true;
- }
-
- return false;
- }
-
- bool hasArg(float& _value, const char _short, const char* _long = NULL) const
- {
- const char* arg = findOption(_short, _long, 1);
- if (NULL != arg)
- {
- _value = float(atof(arg));
- return true;
- }
-
- return false;
- }
-
- bool hasArg(double& _value, const char _short, const char* _long = NULL) const
- {
- const char* arg = findOption(_short, _long, 1);
- if (NULL != arg)
- {
- _value = atof(arg);
- return true;
- }
-
- return false;
- }
-
- bool hasArg(bool& _value, const char _short, const char* _long = NULL) const
- {
- const char* arg = findOption(_short, _long, 1);
- if (NULL != arg)
- {
- if ('0' == *arg || (0 == stricmp(arg, "false") ) )
- {
- _value = false;
- }
- else if ('0' != *arg || (0 == stricmp(arg, "true") ) )
- {
- _value = true;
- }
-
- return true;
- }
-
- return false;
- }
+ ///
+ CommandLine(int32_t _argc, char const* const* _argv);
+
+ ///
+ const char* findOption(const char* _long, const char* _default) const;
+
+ ///
+ const char* findOption(const char _short, const char* _long, const char* _default) const;
+
+ ///
+ const char* findOption(const char* _long, int32_t _numParams = 1) const;
+
+ ///
+ const char* findOption(const char _short, const char* _long = NULL, int32_t _numParams = 1) const;
+
+ ///
+ const char* findOption(int32_t _skip, const char _short, const char* _long = NULL, int32_t _numParams = 1) const;
+
+ ///
+ bool hasArg(const char _short, const char* _long = NULL) const;
+
+ ///
+ bool hasArg(const char* _long) const;
+
+ ///
+ bool hasArg(const char*& _value, const char _short, const char* _long = NULL) const;
+
+ ///
+ bool hasArg(int32_t& _value, const char _short, const char* _long = NULL) const;
+
+ ///
+ bool hasArg(uint32_t& _value, const char _short, const char* _long = NULL) const;
+
+ ///
+ bool hasArg(float& _value, const char _short, const char* _long = NULL) const;
+
+ ///
+ bool hasArg(double& _value, const char _short, const char* _long = NULL) const;
+
+ ///
+ bool hasArg(bool& _value, const char _short, const char* _long = NULL) const;
private:
- const char* find(int _skip, const char _short, const char* _long, int _numParams) const
- {
- for (int ii = 0; ii < m_argc; ++ii)
- {
- const char* arg = m_argv[ii];
- if ('-' == *arg)
- {
- ++arg;
- if (_short == *arg)
- {
- if (1 == strlen(arg) )
- {
- if (0 == _skip)
- {
- if (0 == _numParams)
- {
- return "";
- }
- else if (ii+_numParams < m_argc
- && '-' != *m_argv[ii+1] )
- {
- return m_argv[ii+1];
- }
-
- return NULL;
- }
-
- --_skip;
- ii += _numParams;
- }
- }
- else if (NULL != _long
- && '-' == *arg
- && 0 == stricmp(arg+1, _long) )
- {
- if (0 == _skip)
- {
- if (0 == _numParams)
- {
- return "";
- }
- else if (ii+_numParams < m_argc
- && '-' != *m_argv[ii+1] )
- {
- return m_argv[ii+1];
- }
-
- return NULL;
- }
-
- --_skip;
- ii += _numParams;
- }
- }
- }
-
- return NULL;
- }
-
- int m_argc;
+ ///
+ const char* find(int32_t _skip, const char _short, const char* _long, int32_t _numParams) const;
+
+ int32_t m_argc;
char const* const* m_argv;
};
diff --git a/3rdparty/bx/include/bx/crtimpl.h b/3rdparty/bx/include/bx/crtimpl.h
index b2b3d64c95a..8176c6b9185 100644
--- a/3rdparty/bx/include/bx/crtimpl.h
+++ b/3rdparty/bx/include/bx/crtimpl.h
@@ -9,7 +9,6 @@
#include "bx.h"
#if BX_CONFIG_ALLOCATOR_CRT
-# include <malloc.h>
# include "allocator.h"
#endif // BX_CONFIG_ALLOCATOR_CRT
@@ -20,374 +19,129 @@
namespace bx
{
#if BX_CONFIG_ALLOCATOR_CRT
+ ///
class CrtAllocator : public AllocatorI
{
public:
- CrtAllocator()
- {
- }
-
- virtual ~CrtAllocator()
- {
- }
-
- virtual void* realloc(void* _ptr, size_t _size, size_t _align, const char* _file, uint32_t _line) BX_OVERRIDE
- {
- if (0 == _size)
- {
- if (NULL != _ptr)
- {
- if (BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT >= _align)
- {
- ::free(_ptr);
- return NULL;
- }
-
-# if BX_COMPILER_MSVC
- BX_UNUSED(_file, _line);
- _aligned_free(_ptr);
-# else
- bx::alignedFree(this, _ptr, _align, _file, _line);
-# endif // BX_
- }
-
- return NULL;
- }
- else if (NULL == _ptr)
- {
- if (BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT >= _align)
- {
- return ::malloc(_size);
- }
-
-# if BX_COMPILER_MSVC
- BX_UNUSED(_file, _line);
- return _aligned_malloc(_size, _align);
-# else
- return bx::alignedAlloc(this, _size, _align, _file, _line);
-# endif // BX_
- }
-
- if (BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT >= _align)
- {
- return ::realloc(_ptr, _size);
- }
-
-# if BX_COMPILER_MSVC
- BX_UNUSED(_file, _line);
- return _aligned_realloc(_ptr, _size, _align);
-# else
- return bx::alignedRealloc(this, _ptr, _size, _align, _file, _line);
-# endif // BX_
- }
+ ///
+ CrtAllocator();
+
+ ///
+ virtual ~CrtAllocator();
+
+ ///
+ virtual void* realloc(void* _ptr, size_t _size, size_t _align, const char* _file, uint32_t _line) BX_OVERRIDE;
};
#endif // BX_CONFIG_ALLOCATOR_CRT
#if BX_CONFIG_CRT_FILE_READER_WRITER
-
-# if BX_CRT_MSVC
-# define fseeko64 _fseeki64
-# define ftello64 _ftelli64
-# elif 0 \
- || BX_PLATFORM_ANDROID \
- || BX_PLATFORM_BSD \
- || BX_PLATFORM_IOS \
- || BX_PLATFORM_OSX \
- || BX_PLATFORM_QNX
-# define fseeko64 fseeko
-# define ftello64 ftello
-# elif BX_PLATFORM_PS4
-# define fseeko64 fseek
-# define ftello64 ftell
-# endif // BX_
-
+ ///
class CrtFileReader : public FileReaderI
{
public:
- CrtFileReader()
- : m_file(NULL)
- {
- }
-
- virtual ~CrtFileReader()
- {
- }
-
- virtual bool open(const char* _filePath, Error* _err) BX_OVERRIDE
- {
- BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
-
- if (NULL != m_file)
- {
- BX_ERROR_SET(_err, BX_ERROR_READERWRITER_ALREADY_OPEN, "CrtFileReader: File is already open.");
- return false;
- }
-
- m_file = fopen(_filePath, "rb");
- if (NULL == m_file)
- {
- BX_ERROR_SET(_err, BX_ERROR_READERWRITER_OPEN, "CrtFileReader: Failed to open file.");
- return false;
- }
-
- return true;
- }
-
- virtual void close() BX_OVERRIDE
- {
- BX_CHECK(NULL != m_file, "Reader/Writer file is not open.");
- fclose(m_file);
- m_file = NULL;
- }
-
- virtual int64_t seek(int64_t _offset = 0, Whence::Enum _whence = Whence::Current) BX_OVERRIDE
- {
- BX_CHECK(NULL != m_file, "Reader/Writer file is not open.");
- fseeko64(m_file, _offset, _whence);
- return ftello64(m_file);
- }
-
- virtual int32_t read(void* _data, int32_t _size, Error* _err) BX_OVERRIDE
- {
- BX_CHECK(NULL != m_file, "Reader/Writer file is not open.");
- BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
-
- int32_t size = (int32_t)fread(_data, 1, _size, m_file);
- if (size != _size)
- {
- if (0 != feof(m_file) )
- {
- BX_ERROR_SET(_err, BX_ERROR_READERWRITER_EOF, "CrtFileReader: EOF.");
- }
- else if (0 != ferror(m_file) )
- {
- BX_ERROR_SET(_err, BX_ERROR_READERWRITER_READ, "CrtFileReader: read error.");
- }
-
- return size >= 0 ? size : 0;
- }
-
- return size;
- }
+ ///
+ CrtFileReader();
+
+ ///
+ virtual ~CrtFileReader();
+
+ ///
+ virtual bool open(const char* _filePath, Error* _err) BX_OVERRIDE;
+
+ ///
+ virtual void close() BX_OVERRIDE;
+
+ ///
+ virtual int64_t seek(int64_t _offset = 0, Whence::Enum _whence = Whence::Current) BX_OVERRIDE;
+
+ ///
+ virtual int32_t read(void* _data, int32_t _size, Error* _err) BX_OVERRIDE;
private:
- FILE* m_file;
+ void* m_file;
};
+ ///
class CrtFileWriter : public FileWriterI
{
public:
- CrtFileWriter()
- : m_file(NULL)
- {
- }
-
- virtual ~CrtFileWriter()
- {
- }
-
- virtual bool open(const char* _filePath, bool _append, Error* _err) BX_OVERRIDE
- {
- BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
-
- if (NULL != m_file)
- {
- BX_ERROR_SET(_err, BX_ERROR_READERWRITER_ALREADY_OPEN, "CrtFileReader: File is already open.");
- return false;
- }
-
- m_file = fopen(_filePath, _append ? "ab" : "wb");
-
- if (NULL == m_file)
- {
- BX_ERROR_SET(_err, BX_ERROR_READERWRITER_OPEN, "CrtFileWriter: Failed to open file.");
- return false;
- }
-
- return true;
- }
-
- virtual void close() BX_OVERRIDE
- {
- BX_CHECK(NULL != m_file, "Reader/Writer file is not open.");
- fclose(m_file);
- m_file = NULL;
- }
-
- virtual int64_t seek(int64_t _offset = 0, Whence::Enum _whence = Whence::Current) BX_OVERRIDE
- {
- BX_CHECK(NULL != m_file, "Reader/Writer file is not open.");
- fseeko64(m_file, _offset, _whence);
- return ftello64(m_file);
- }
-
- virtual int32_t write(const void* _data, int32_t _size, Error* _err) BX_OVERRIDE
- {
- BX_CHECK(NULL != m_file, "Reader/Writer file is not open.");
- BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
-
- int32_t size = (int32_t)fwrite(_data, 1, _size, m_file);
- if (size != _size)
- {
- BX_ERROR_SET(_err, BX_ERROR_READERWRITER_WRITE, "CrtFileWriter: write failed.");
- return size >= 0 ? size : 0;
- }
-
- return size;
- }
+ ///
+ CrtFileWriter();
+
+ ///
+ virtual ~CrtFileWriter();
+
+ ///
+ virtual bool open(const char* _filePath, bool _append, Error* _err) BX_OVERRIDE;
+
+ ///
+ virtual void close() BX_OVERRIDE;
+
+ ///
+ virtual int64_t seek(int64_t _offset = 0, Whence::Enum _whence = Whence::Current) BX_OVERRIDE;
+
+ ///
+ virtual int32_t write(const void* _data, int32_t _size, Error* _err) BX_OVERRIDE;
private:
- FILE* m_file;
+ void* m_file;
};
#endif // BX_CONFIG_CRT_FILE_READER_WRITER
#if BX_CONFIG_CRT_PROCESS
-
-#if BX_CRT_MSVC
-# define popen _popen
-# define pclose _pclose
-#endif // BX_CRT_MSVC
-
+ ///
class ProcessReader : public ReaderOpenI, public CloserI, public ReaderI
{
public:
- ProcessReader()
- : m_file(NULL)
- {
- }
-
- ~ProcessReader()
- {
- BX_CHECK(NULL == m_file, "Process not closed!");
- }
-
- virtual bool open(const char* _command, Error* _err) BX_OVERRIDE
- {
- BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
-
- if (NULL != m_file)
- {
- BX_ERROR_SET(_err, BX_ERROR_READERWRITER_ALREADY_OPEN, "ProcessReader: File is already open.");
- return false;
- }
-
- m_file = popen(_command, "r");
- if (NULL == m_file)
- {
- BX_ERROR_SET(_err, BX_ERROR_READERWRITER_OPEN, "ProcessReader: Failed to open process.");
- return false;
- }
-
- return true;
- }
-
- virtual void close() BX_OVERRIDE
- {
- BX_CHECK(NULL != m_file, "Process not open!");
- m_exitCode = pclose(m_file);
- m_file = NULL;
- }
-
- virtual int32_t read(void* _data, int32_t _size, Error* _err) BX_OVERRIDE
- {
- BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); BX_UNUSED(_err);
-
- int32_t size = (int32_t)fread(_data, 1, _size, m_file);
- if (size != _size)
- {
- if (0 != feof(m_file) )
- {
- BX_ERROR_SET(_err, BX_ERROR_READERWRITER_EOF, "ProcessReader: EOF.");
- }
- else if (0 != ferror(m_file) )
- {
- BX_ERROR_SET(_err, BX_ERROR_READERWRITER_READ, "ProcessReader: read error.");
- }
-
- return size >= 0 ? size : 0;
- }
-
- return size;
- }
-
- int32_t getExitCode() const
- {
- return m_exitCode;
- }
+ ///
+ ProcessReader();
+
+ ///
+ ~ProcessReader();
+
+ ///
+ virtual bool open(const char* _command, Error* _err) BX_OVERRIDE;
+
+ ///
+ virtual void close() BX_OVERRIDE;
+
+ ///
+ virtual int32_t read(void* _data, int32_t _size, Error* _err) BX_OVERRIDE;
+
+ ///
+ int32_t getExitCode() const;
private:
- FILE* m_file;
+ void* m_file;
int32_t m_exitCode;
};
+ ///
class ProcessWriter : public WriterOpenI, public CloserI, public WriterI
{
public:
- ProcessWriter()
- : m_file(NULL)
- {
- }
-
- ~ProcessWriter()
- {
- BX_CHECK(NULL == m_file, "Process not closed!");
- }
-
- virtual bool open(const char* _command, bool, Error* _err) BX_OVERRIDE
- {
- BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
-
- if (NULL != m_file)
- {
- BX_ERROR_SET(_err, BX_ERROR_READERWRITER_ALREADY_OPEN, "ProcessWriter: File is already open.");
- return false;
- }
-
- m_file = popen(_command, "w");
- if (NULL == m_file)
- {
- BX_ERROR_SET(_err, BX_ERROR_READERWRITER_OPEN, "ProcessWriter: Failed to open process.");
- return false;
- }
-
- return true;
- }
-
- virtual void close() BX_OVERRIDE
- {
- BX_CHECK(NULL != m_file, "Process not open!");
- m_exitCode = pclose(m_file);
- m_file = NULL;
- }
-
- virtual int32_t write(const void* _data, int32_t _size, Error* _err) BX_OVERRIDE
- {
- BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); BX_UNUSED(_err);
-
- int32_t size = (int32_t)fwrite(_data, 1, _size, m_file);
- if (size != _size)
- {
- if (0 != ferror(m_file) )
- {
- BX_ERROR_SET(_err, BX_ERROR_READERWRITER_WRITE, "ProcessWriter: write error.");
- }
-
- return size >= 0 ? size : 0;
- }
-
- return size;
- }
-
- int32_t getExitCode() const
- {
- return m_exitCode;
- }
+ ///
+ ProcessWriter();
+
+ ///
+ ~ProcessWriter();
+
+ ///
+ virtual bool open(const char* _command, bool, Error* _err) BX_OVERRIDE;
+
+ ///
+ virtual void close() BX_OVERRIDE;
+
+ ///
+ virtual int32_t write(const void* _data, int32_t _size, Error* _err) BX_OVERRIDE;
+
+ ///
+ int32_t getExitCode() const;
private:
- FILE* m_file;
+ void* m_file;
int32_t m_exitCode;
};
-
#endif // BX_CONFIG_CRT_PROCESS
} // namespace bx
diff --git a/3rdparty/bx/include/bx/debug.h b/3rdparty/bx/include/bx/debug.h
index c94f744aad2..641a0ed82bf 100644
--- a/3rdparty/bx/include/bx/debug.h
+++ b/3rdparty/bx/include/bx/debug.h
@@ -7,69 +7,24 @@
#define BX_DEBUG_H_HEADER_GUARD
#include "bx.h"
-
-#if BX_PLATFORM_ANDROID
-# include <android/log.h>
-#elif BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT || BX_PLATFORM_XBOX360 || BX_PLATFORM_XBOXONE
-extern "C" __declspec(dllimport) void __stdcall OutputDebugStringA(const char* _str);
-#elif BX_PLATFORM_IOS || BX_PLATFORM_OSX
-# if defined(__OBJC__)
-# import <Foundation/NSObjCRuntime.h>
-# else
-# include <CoreFoundation/CFString.h>
-extern "C" void NSLog(CFStringRef _format, ...);
-# endif // defined(__OBJC__)
-#elif 0 // BX_PLATFORM_EMSCRIPTEN
-# include <emscripten.h>
-#else
-# include <stdio.h>
-#endif // BX_PLATFORM_WINDOWS
+#include <stdarg.h> // va_list
namespace bx
{
-#if BX_COMPILER_CLANG_ANALYZER
- inline __attribute__((analyzer_noreturn)) void debugBreak();
-#endif // BX_COMPILER_CLANG_ANALYZER
+ ///
+ void debugBreak();
+
+ ///
+ void debugOutput(const char* _out);
+
+ ///
+ void debugPrintfVargs(const char* _format, va_list _argList);
- inline void debugBreak()
- {
-#if BX_COMPILER_MSVC
- __debugbreak();
-#elif BX_CPU_ARM
- __builtin_trap();
-// asm("bkpt 0");
-#elif !BX_PLATFORM_NACL && BX_CPU_X86 && (BX_COMPILER_GCC || BX_COMPILER_CLANG)
- // NaCl doesn't like int 3:
- // NativeClient: NaCl module load failed: Validation failure. File violates Native Client safety rules.
- __asm__ ("int $3");
-#else // cross platform implementation
- int* int3 = (int*)3L;
- *int3 = 3;
-#endif // BX
- }
+ ///
+ void debugPrintf(const char* _format, ...);
- inline void debugOutput(const char* _out)
- {
-#if BX_PLATFORM_ANDROID
-# ifndef BX_ANDROID_LOG_TAG
-# define BX_ANDROID_LOG_TAG ""
-# endif // BX_ANDROID_LOG_TAG
- __android_log_write(ANDROID_LOG_DEBUG, BX_ANDROID_LOG_TAG, _out);
-#elif BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT || BX_PLATFORM_XBOX360 || BX_PLATFORM_XBOXONE
- OutputDebugStringA(_out);
-#elif BX_PLATFORM_IOS || BX_PLATFORM_OSX
-# if defined(__OBJC__)
- NSLog(@"%s", _out);
-# else
- NSLog(__CFStringMakeConstantString("%s"), _out);
-# endif // defined(__OBJC__)
-#elif 0 // BX_PLATFORM_EMSCRIPTEN
- emscripten_log(EM_LOG_CONSOLE, "%s", _out);
-#else
- fputs(_out, stdout);
- fflush(stdout);
-#endif // BX_PLATFORM_
- }
+ ///
+ void debugPrintfData(const void* _data, uint32_t _size, const char* _format, ...);
} // namespace bx
diff --git a/3rdparty/bx/include/bx/easing.h b/3rdparty/bx/include/bx/easing.h
index 3db6eec53a2..9efbc515378 100644
--- a/3rdparty/bx/include/bx/easing.h
+++ b/3rdparty/bx/include/bx/easing.h
@@ -14,6 +14,7 @@
namespace bx
{
+ ///
struct Easing
{
enum Enum
@@ -64,252 +65,134 @@ namespace bx
};
};
+ ///
typedef float (*EaseFn)(float _t);
- template<EaseFn ease>
- float easeOut(float _t)
- {
- return 1.0f - ease(1.0f - _t);
- }
+ ///
+ float easeLinear(float _t);
- template<EaseFn easeFrom0toH, EaseFn easeFromHto1>
- float easeMix(float _t)
- {
- return _t < 0.5f
- ? easeFrom0toH(2.0f*_t)*0.5f
- : easeFromHto1(2.0f*_t - 1.0f)*0.5f + 0.5f
- ;
- }
+ ///
+ float easeInQuad(float _t);
- inline float easeLinear(float _t)
- {
- return _t;
- }
+ ///
+ float easeOutQuad(float _t);
- inline float easeInQuad(float _t)
- {
- return fsq(_t);
- }
+ ///
+ float easeInOutQuad(float _t);
- inline float easeOutQuad(float _t)
- {
- return easeOut<easeInQuad>(_t);
- }
+ ///
+ float easeOutInQuad(float _t);
- inline float easeInOutQuad(float _t)
- {
- return easeMix<easeInQuad, easeOutQuad>(_t);
- }
+ ///
+ float easeInCubic(float _t);
- inline float easeOutInQuad(float _t)
- {
- return easeMix<easeOutQuad, easeInQuad>(_t);
- }
+ ///
+ float easeOutCubic(float _t);
- inline float easeInCubic(float _t)
- {
- return _t*_t*_t;
- }
+ ///
+ float easeInOutCubic(float _t);
- inline float easeOutCubic(float _t)
- {
- return easeOut<easeInCubic>(_t);
- }
+ ///
+ float easeOutInCubic(float _t);
- inline float easeInOutCubic(float _t)
- {
- return easeMix<easeInCubic, easeOutCubic>(_t);
- }
+ ///
+ float easeInQuart(float _t);
- inline float easeOutInCubic(float _t)
- {
- return easeMix<easeOutCubic, easeInCubic>(_t);
- }
+ ///
+ float easeOutQuart(float _t);
- inline float easeInQuart(float _t)
- {
- return _t*_t*_t*_t;
- }
+ ///
+ float easeInOutQuart(float _t);
- inline float easeOutQuart(float _t)
- {
- return easeOut<easeInQuart>(_t);
- }
+ ///
+ float easeOutInQuart(float _t);
- inline float easeInOutQuart(float _t)
- {
- return easeMix<easeInQuart, easeOutQuart>(_t);
- }
-
- inline float easeOutInQuart(float _t)
- {
- return easeMix<easeOutQuart, easeInQuart>(_t);
- }
-
- inline float easeInQuint(float _t)
- {
- return _t*_t*_t*_t*_t;
- }
-
- inline float easeOutQuint(float _t)
- {
- return easeOut<easeInQuint>(_t);
- }
+ ///
+ float easeInQuint(float _t);
- inline float easeInOutQuint(float _t)
- {
- return easeMix<easeInQuint, easeOutQuint>(_t);
- }
+ ///
+ float easeOutQuint(float _t);
- inline float easeOutInQuint(float _t)
- {
- return easeMix<easeOutQuint, easeInQuint>(_t);
- }
+ ///
+ float easeInOutQuint(float _t);
- inline float easeInSine(float _t)
- {
- return 1.0f - fcos(_t*piHalf);
- }
+ ///
+ float easeOutInQuint(float _t);
- inline float easeOutSine(float _t)
- {
- return easeOut<easeInSine>(_t);
- }
+ ///
+ float easeInSine(float _t);
- inline float easeInOutSine(float _t)
- {
- return easeMix<easeInSine, easeOutSine>(_t);
- }
+ ///
+ float easeOutSine(float _t);
- inline float easeOutInSine(float _t)
- {
- return easeMix<easeOutSine, easeInSine>(_t);
- }
+ ///
+ float easeInOutSine(float _t);
- inline float easeInExpo(float _t)
- {
- return fpow(2.0f, 10.0f * (_t - 1.0f) ) - 0.001f;
- }
+ ///
+ float easeOutInSine(float _t);
- inline float easeOutExpo(float _t)
- {
- return easeOut<easeInExpo>(_t);
- }
+ ///
+ float easeInExpo(float _t);
- inline float easeInOutExpo(float _t)
- {
- return easeMix<easeInExpo, easeOutExpo>(_t);
- }
+ ///
+ float easeOutExpo(float _t);
- inline float easeOutInExpo(float _t)
- {
- return easeMix<easeOutExpo, easeInExpo>(_t);
- }
+ ///
+ float easeInOutExpo(float _t);
- inline float easeInCirc(float _t)
- {
- return -(fsqrt(1.0f - _t*_t) - 1.0f);
- }
+ ///
+ float easeOutInExpo(float _t);
- inline float easeOutCirc(float _t)
- {
- return easeOut<easeInCirc>(_t);
- }
+ ///
+ float easeInCirc(float _t);
- inline float easeInOutCirc(float _t)
- {
- return easeMix<easeInCirc, easeOutCirc>(_t);
- }
+ ///
+ float easeOutCirc(float _t);
- inline float easeOutInCirc(float _t)
- {
- return easeMix<easeOutCirc, easeInCirc>(_t);
- }
+ ///
+ float easeInOutCirc(float _t);
- inline float easeOutElastic(float _t)
- {
- return fpow(2.0f, -10.0f*_t)*fsin( (_t-0.3f/4.0f)*(2.0f*pi)/0.3f) + 1.0f;
- }
+ ///
+ float easeOutInCirc(float _t);
- inline float easeInElastic(float _t)
- {
- return easeOut<easeOutElastic>(_t);
- }
+ ///
+ float easeOutElastic(float _t);
- inline float easeInOutElastic(float _t)
- {
- return easeMix<easeInElastic, easeOutElastic>(_t);
- }
+ ///
+ float easeInElastic(float _t);
- inline float easeOutInElastic(float _t)
- {
- return easeMix<easeOutElastic, easeInElastic>(_t);
- }
+ ///
+ float easeInOutElastic(float _t);
- inline float easeInBack(float _t)
- {
- return easeInCubic(_t) - _t*fsin(_t*pi);
- }
+ ///
+ float easeOutInElastic(float _t);
- inline float easeOutBack(float _t)
- {
- return easeOut<easeInBack>(_t);
- }
+ ///
+ float easeInBack(float _t);
- inline float easeInOutBack(float _t)
- {
- return easeMix<easeInBack, easeOutBack>(_t);
- }
+ ///
+ float easeOutBack(float _t);
- inline float easeOutInBack(float _t)
- {
- return easeMix<easeOutBack, easeInBack>(_t);
- }
+ ///
+ float easeInOutBack(float _t);
- inline float easeOutBounce(float _t)
- {
- if (4.0f/11.0f > _t)
- {
- return 121.0f/16.0f*_t*_t;
- }
+ ///
+ float easeOutInBack(float _t);
- if (8.0f/11.0f > _t)
- {
- return 363.0f/40.0f*_t*_t
- - 99.0f/10.0f*_t
- + 17.0f/ 5.0f
- ;
- }
+ ///
+ float easeOutBounce(float _t);
- if (9.0f/10.0f > _t)
- {
- return 4356.0f/ 361.0f*_t*_t
- - 35442.0f/1805.0f*_t
- + 16061.0f/1805.0f
- ;
- }
-
- return 54.0f/ 5.0f*_t*_t
- - 513.0f/25.0f*_t
- + 268.0f/25.0f
- ;
- }
-
- inline float easeInBounce(float _t)
- {
- return easeOut<easeOutBounce>(_t);
- }
+ ///
+ float easeInBounce(float _t);
- inline float easeInOutBounce(float _t)
- {
- return easeMix<easeInBounce, easeOutBounce>(_t);
- }
+ ///
+ float easeInOutBounce(float _t);
- inline float easeOutInBounce(float _t)
- {
- return easeMix<easeOutBounce, easeInBounce>(_t);
- }
+ ///
+ float easeOutInBounce(float _t);
} // namespace bx
+#include "easing.inl"
+
#endif // BX_EASING_H_HEADER_GUARD
diff --git a/3rdparty/bx/include/bx/easing.inl b/3rdparty/bx/include/bx/easing.inl
new file mode 100644
index 00000000000..b23edb1128a
--- /dev/null
+++ b/3rdparty/bx/include/bx/easing.inl
@@ -0,0 +1,256 @@
+/*
+ * Copyright 2011-2017 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ */
+
+#ifndef BX_EASING_H_HEADER_GUARD
+# error "Must be included from bx/easing.h!"
+#endif // BX_EASING_H_HEADER_GUARD
+
+namespace bx
+{
+ template<EaseFn ease>
+ float easeOut(float _t)
+ {
+ return 1.0f - ease(1.0f - _t);
+ }
+
+ template<EaseFn easeFrom0toH, EaseFn easeFromHto1>
+ float easeMix(float _t)
+ {
+ return _t < 0.5f
+ ? easeFrom0toH(2.0f*_t)*0.5f
+ : easeFromHto1(2.0f*_t - 1.0f)*0.5f + 0.5f
+ ;
+ }
+
+ inline float easeLinear(float _t)
+ {
+ return _t;
+ }
+
+ inline float easeInQuad(float _t)
+ {
+ return fsq(_t);
+ }
+
+ inline float easeOutQuad(float _t)
+ {
+ return easeOut<easeInQuad>(_t);
+ }
+
+ inline float easeInOutQuad(float _t)
+ {
+ return easeMix<easeInQuad, easeOutQuad>(_t);
+ }
+
+ inline float easeOutInQuad(float _t)
+ {
+ return easeMix<easeOutQuad, easeInQuad>(_t);
+ }
+
+ inline float easeInCubic(float _t)
+ {
+ return _t*_t*_t;
+ }
+
+ inline float easeOutCubic(float _t)
+ {
+ return easeOut<easeInCubic>(_t);
+ }
+
+ inline float easeInOutCubic(float _t)
+ {
+ return easeMix<easeInCubic, easeOutCubic>(_t);
+ }
+
+ inline float easeOutInCubic(float _t)
+ {
+ return easeMix<easeOutCubic, easeInCubic>(_t);
+ }
+
+ inline float easeInQuart(float _t)
+ {
+ return _t*_t*_t*_t;
+ }
+
+ inline float easeOutQuart(float _t)
+ {
+ return easeOut<easeInQuart>(_t);
+ }
+
+ inline float easeInOutQuart(float _t)
+ {
+ return easeMix<easeInQuart, easeOutQuart>(_t);
+ }
+
+ inline float easeOutInQuart(float _t)
+ {
+ return easeMix<easeOutQuart, easeInQuart>(_t);
+ }
+
+ inline float easeInQuint(float _t)
+ {
+ return _t*_t*_t*_t*_t;
+ }
+
+ inline float easeOutQuint(float _t)
+ {
+ return easeOut<easeInQuint>(_t);
+ }
+
+ inline float easeInOutQuint(float _t)
+ {
+ return easeMix<easeInQuint, easeOutQuint>(_t);
+ }
+
+ inline float easeOutInQuint(float _t)
+ {
+ return easeMix<easeOutQuint, easeInQuint>(_t);
+ }
+
+ inline float easeInSine(float _t)
+ {
+ return 1.0f - fcos(_t*piHalf);
+ }
+
+ inline float easeOutSine(float _t)
+ {
+ return easeOut<easeInSine>(_t);
+ }
+
+ inline float easeInOutSine(float _t)
+ {
+ return easeMix<easeInSine, easeOutSine>(_t);
+ }
+
+ inline float easeOutInSine(float _t)
+ {
+ return easeMix<easeOutSine, easeInSine>(_t);
+ }
+
+ inline float easeInExpo(float _t)
+ {
+ return fpow(2.0f, 10.0f * (_t - 1.0f) ) - 0.001f;
+ }
+
+ inline float easeOutExpo(float _t)
+ {
+ return easeOut<easeInExpo>(_t);
+ }
+
+ inline float easeInOutExpo(float _t)
+ {
+ return easeMix<easeInExpo, easeOutExpo>(_t);
+ }
+
+ inline float easeOutInExpo(float _t)
+ {
+ return easeMix<easeOutExpo, easeInExpo>(_t);
+ }
+
+ inline float easeInCirc(float _t)
+ {
+ return -(fsqrt(1.0f - _t*_t) - 1.0f);
+ }
+
+ inline float easeOutCirc(float _t)
+ {
+ return easeOut<easeInCirc>(_t);
+ }
+
+ inline float easeInOutCirc(float _t)
+ {
+ return easeMix<easeInCirc, easeOutCirc>(_t);
+ }
+
+ inline float easeOutInCirc(float _t)
+ {
+ return easeMix<easeOutCirc, easeInCirc>(_t);
+ }
+
+ inline float easeOutElastic(float _t)
+ {
+ return fpow(2.0f, -10.0f*_t)*fsin( (_t-0.3f/4.0f)*(2.0f*pi)/0.3f) + 1.0f;
+ }
+
+ inline float easeInElastic(float _t)
+ {
+ return easeOut<easeOutElastic>(_t);
+ }
+
+ inline float easeInOutElastic(float _t)
+ {
+ return easeMix<easeInElastic, easeOutElastic>(_t);
+ }
+
+ inline float easeOutInElastic(float _t)
+ {
+ return easeMix<easeOutElastic, easeInElastic>(_t);
+ }
+
+ inline float easeInBack(float _t)
+ {
+ return easeInCubic(_t) - _t*fsin(_t*pi);
+ }
+
+ inline float easeOutBack(float _t)
+ {
+ return easeOut<easeInBack>(_t);
+ }
+
+ inline float easeInOutBack(float _t)
+ {
+ return easeMix<easeInBack, easeOutBack>(_t);
+ }
+
+ inline float easeOutInBack(float _t)
+ {
+ return easeMix<easeOutBack, easeInBack>(_t);
+ }
+
+ inline float easeOutBounce(float _t)
+ {
+ if (4.0f/11.0f > _t)
+ {
+ return 121.0f/16.0f*_t*_t;
+ }
+
+ if (8.0f/11.0f > _t)
+ {
+ return 363.0f/40.0f*_t*_t
+ - 99.0f/10.0f*_t
+ + 17.0f/ 5.0f
+ ;
+ }
+
+ if (9.0f/10.0f > _t)
+ {
+ return 4356.0f/ 361.0f*_t*_t
+ - 35442.0f/1805.0f*_t
+ + 16061.0f/1805.0f
+ ;
+ }
+
+ return 54.0f/ 5.0f*_t*_t
+ - 513.0f/25.0f*_t
+ + 268.0f/25.0f
+ ;
+ }
+
+ inline float easeInBounce(float _t)
+ {
+ return easeOut<easeOutBounce>(_t);
+ }
+
+ inline float easeInOutBounce(float _t)
+ {
+ return easeMix<easeInBounce, easeOutBounce>(_t);
+ }
+
+ inline float easeOutInBounce(float _t)
+ {
+ return easeMix<easeOutBounce, easeInBounce>(_t);
+ }
+
+} // namespace bx
diff --git a/3rdparty/bx/include/bx/endian.h b/3rdparty/bx/include/bx/endian.h
index 23e9a665b63..c687d4fa0f2 100644
--- a/3rdparty/bx/include/bx/endian.h
+++ b/3rdparty/bx/include/bx/endian.h
@@ -10,78 +10,41 @@
namespace bx
{
- inline uint16_t endianSwap(uint16_t _in)
- {
- return (_in>>8) | (_in<<8);
- }
-
- inline uint32_t endianSwap(uint32_t _in)
- {
- return (_in>>24) | (_in<<24)
- | ( (_in&0x00ff0000)>>8) | ( (_in&0x0000ff00)<<8)
- ;
- }
+ ///
+ int16_t endianSwap(int16_t _in);
- inline uint64_t endianSwap(uint64_t _in)
- {
- return (_in>>56) | (_in<<56)
- | ( (_in&UINT64_C(0x00ff000000000000) )>>40) | ( (_in&UINT64_C(0x000000000000ff00) )<<40)
- | ( (_in&UINT64_C(0x0000ff0000000000) )>>24) | ( (_in&UINT64_C(0x0000000000ff0000) )<<24)
- | ( (_in&UINT64_C(0x000000ff00000000) )>>8) | ( (_in&UINT64_C(0x00000000ff000000) )<<8)
- ;
- }
+ ///
+ uint16_t endianSwap(uint16_t _in);
- inline int16_t endianSwap(int16_t _in)
- {
- return (int16_t)endianSwap( (uint16_t)_in);
- }
+ ///
+ int32_t endianSwap(int32_t _in);
- inline int32_t endianSwap(int32_t _in)
- {
- return (int32_t)endianSwap( (uint32_t)_in);
- }
+ ///
+ uint32_t endianSwap(uint32_t _in);
- inline int64_t endianSwap(int64_t _in)
- {
- return (int64_t)endianSwap( (uint64_t)_in);
- }
+ ///
+ int64_t endianSwap(int64_t _in);
+
+ ///
+ uint64_t endianSwap(uint64_t _in);
/// Input argument is encoded as little endian, convert it if neccessary
/// depending on host CPU endianess.
template <typename Ty>
- inline Ty toLittleEndian(const Ty _in)
- {
-#if BX_CPU_ENDIAN_BIG
- return endianSwap(_in);
-#else
- return _in;
-#endif // BX_CPU_ENDIAN_BIG
- }
+ Ty toLittleEndian(const Ty _in);
/// Input argument is encoded as big endian, convert it if neccessary
/// depending on host CPU endianess.
template <typename Ty>
- inline Ty toBigEndian(const Ty _in)
- {
-#if BX_CPU_ENDIAN_LITTLE
- return endianSwap(_in);
-#else
- return _in;
-#endif // BX_CPU_ENDIAN_LITTLE
- }
+ Ty toBigEndian(const Ty _in);
/// If _littleEndian is true, converts input argument to from little endian
/// to host CPU endiness.
template <typename Ty>
- inline Ty toHostEndian(const Ty _in, bool _fromLittleEndian)
- {
-#if BX_CPU_ENDIAN_LITTLE
- return _fromLittleEndian ? _in : endianSwap(_in);
-#else
- return _fromLittleEndian ? endianSwap(_in) : _in;
-#endif // BX_CPU_ENDIAN_LITTLE
- }
+ Ty toHostEndian(const Ty _in, bool _fromLittleEndian);
} // namespace bx
+#include "endian.inl"
+
#endif // BX_ENDIAN_H_HEADER_GUARD
diff --git a/3rdparty/bx/include/bx/endian.inl b/3rdparty/bx/include/bx/endian.inl
new file mode 100644
index 00000000000..6ec7572c71c
--- /dev/null
+++ b/3rdparty/bx/include/bx/endian.inl
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2010-2017 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ */
+
+#ifndef BX_ENDIAN_H_HEADER_GUARD
+# error "Must be included from bx/endian.h!"
+#endif // BX_ENDIAN_H_HEADER_GUARD
+
+namespace bx
+{
+ inline int16_t endianSwap(int16_t _in)
+ {
+ return (int16_t)endianSwap( (uint16_t)_in);
+ }
+
+ inline uint16_t endianSwap(uint16_t _in)
+ {
+ return (_in>>8) | (_in<<8);
+ }
+
+ inline int32_t endianSwap(int32_t _in)
+ {
+ return (int32_t)endianSwap( (uint32_t)_in);
+ }
+
+ inline uint32_t endianSwap(uint32_t _in)
+ {
+ return ( _in >>24) | ( _in <<24)
+ | ( (_in&0x00ff0000)>> 8) | ( (_in&0x0000ff00)<< 8)
+ ;
+ }
+
+ inline int64_t endianSwap(int64_t _in)
+ {
+ return (int64_t)endianSwap( (uint64_t)_in);
+ }
+
+ inline uint64_t endianSwap(uint64_t _in)
+ {
+ return (_in >>56) | ( _in <<56)
+ | ( (_in&UINT64_C(0x00ff000000000000) )>>40) | ( (_in&UINT64_C(0x000000000000ff00) )<<40)
+ | ( (_in&UINT64_C(0x0000ff0000000000) )>>24) | ( (_in&UINT64_C(0x0000000000ff0000) )<<24)
+ | ( (_in&UINT64_C(0x000000ff00000000) )>> 8) | ( (_in&UINT64_C(0x00000000ff000000) )<< 8)
+ ;
+ }
+
+ template <typename Ty>
+ inline Ty toLittleEndian(const Ty _in)
+ {
+#if BX_CPU_ENDIAN_BIG
+ return endianSwap(_in);
+#else
+ return _in;
+#endif // BX_CPU_ENDIAN_BIG
+ }
+
+ template <typename Ty>
+ inline Ty toBigEndian(const Ty _in)
+ {
+#if BX_CPU_ENDIAN_LITTLE
+ return endianSwap(_in);
+#else
+ return _in;
+#endif // BX_CPU_ENDIAN_LITTLE
+ }
+
+ template <typename Ty>
+ inline Ty toHostEndian(const Ty _in, bool _fromLittleEndian)
+ {
+#if BX_CPU_ENDIAN_LITTLE
+ return _fromLittleEndian ? _in : endianSwap(_in);
+#else
+ return _fromLittleEndian ? endianSwap(_in) : _in;
+#endif // BX_CPU_ENDIAN_LITTLE
+ }
+
+} // namespace bx
diff --git a/3rdparty/bx/include/bx/error.h b/3rdparty/bx/include/bx/error.h
index 598d5689c6c..72a8444342c 100644
--- a/3rdparty/bx/include/bx/error.h
+++ b/3rdparty/bx/include/bx/error.h
@@ -44,55 +44,29 @@ namespace bx
);
public:
- Error()
- : m_code(0)
- {
- }
-
- void reset()
- {
- m_code = 0;
- m_msg.clear();
- }
-
- void setError(ErrorResult _errorResult, const StringView& _msg)
- {
- BX_CHECK(0 != _errorResult.code, "Invalid ErrorResult passed to setError!");
-
- if (!isOk() )
- {
- return;
- }
-
- m_code = _errorResult.code;
- m_msg = _msg;
- }
-
- bool isOk() const
- {
- return 0 == m_code;
- }
-
- ErrorResult get() const
- {
- ErrorResult result = { m_code };
- return result;
- }
-
- const StringView& getMessage() const
- {
- return m_msg;
- }
-
- bool operator==(const ErrorResult& _rhs) const
- {
- return _rhs.code == m_code;
- }
-
- bool operator!=(const ErrorResult& _rhs) const
- {
- return _rhs.code != m_code;
- }
+ ///
+ Error();
+
+ ///
+ void reset();
+
+ ///
+ void setError(ErrorResult _errorResult, const StringView& _msg);
+
+ ///
+ bool isOk() const;
+
+ ///
+ ErrorResult get() const;
+
+ ///
+ const StringView& getMessage() const;
+
+ ///
+ bool operator==(const ErrorResult& _rhs) const;
+
+ ///
+ bool operator!=(const ErrorResult& _rhs) const;
private:
StringView m_msg;
@@ -108,16 +82,11 @@ namespace bx
);
public:
- ErrorScope(Error* _err)
- : m_err(_err)
- {
- BX_CHECK(NULL != _err, "_err can't be NULL");
- }
+ ///
+ ErrorScope(Error* _err);
- ~ErrorScope()
- {
- BX_CHECK(m_err->isOk(), "Error: %d", m_err->get().code);
- }
+ ///
+ ~ErrorScope();
private:
Error* m_err;
@@ -125,4 +94,6 @@ namespace bx
} // namespace bx
+#include "error.inl"
+
#endif // BX_ERROR_H_HEADER_GUARD
diff --git a/3rdparty/bx/include/bx/error.inl b/3rdparty/bx/include/bx/error.inl
new file mode 100644
index 00000000000..ac16c6f9841
--- /dev/null
+++ b/3rdparty/bx/include/bx/error.inl
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2010-2017 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ */
+
+#ifndef BX_ERROR_H_HEADER_GUARD
+# error "Must be included from bx/error!"
+#endif // BX_ERROR_H_HEADER_GUARD
+
+namespace bx
+{
+ inline Error::Error()
+ : m_code(0)
+ {
+ }
+
+ inline void Error::reset()
+ {
+ m_code = 0;
+ m_msg.clear();
+ }
+
+ inline void Error::setError(ErrorResult _errorResult, const StringView& _msg)
+ {
+ BX_CHECK(0 != _errorResult.code, "Invalid ErrorResult passed to setError!");
+
+ if (!isOk() )
+ {
+ return;
+ }
+
+ m_code = _errorResult.code;
+ m_msg = _msg;
+ }
+
+ inline bool Error::isOk() const
+ {
+ return 0 == m_code;
+ }
+
+ inline ErrorResult Error::get() const
+ {
+ ErrorResult result = { m_code };
+ return result;
+ }
+
+ inline const StringView& Error::getMessage() const
+ {
+ return m_msg;
+ }
+
+ inline bool Error::operator==(const ErrorResult& _rhs) const
+ {
+ return _rhs.code == m_code;
+ }
+
+ inline bool Error::operator!=(const ErrorResult& _rhs) const
+ {
+ return _rhs.code != m_code;
+ }
+
+ inline ErrorScope::ErrorScope(Error* _err)
+ : m_err(_err)
+ {
+ BX_CHECK(NULL != _err, "_err can't be NULL");
+ }
+
+ inline ErrorScope::~ErrorScope()
+ {
+ BX_CHECK(m_err->isOk(), "Error: %d", m_err->get().code);
+ }
+
+} // namespace bx
diff --git a/3rdparty/bx/include/bx/foreach.h b/3rdparty/bx/include/bx/foreach.h
deleted file mode 100644
index 53a6dde7265..00000000000
--- a/3rdparty/bx/include/bx/foreach.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright 2010-2017 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
- */
-
-#ifndef BX_FOREACH_H_HEADER_GUARD
-#define BX_FOREACH_H_HEADER_GUARD
-
-#include "bx.h"
-
-namespace bx
-{
- namespace foreach_ns
- {
- struct ContainerBase
- {
- };
-
- template <typename Ty>
- class Container : public ContainerBase
- {
- public:
- inline Container(const Ty& _container)
- : m_container(_container)
- , m_break(0)
- , m_it( _container.begin() )
- , m_itEnd( _container.end() )
- {
- }
-
- inline bool condition() const
- {
- return (!m_break++ && m_it != m_itEnd);
- }
-
- const Ty& m_container;
- mutable int m_break;
- mutable typename Ty::const_iterator m_it;
- mutable typename Ty::const_iterator m_itEnd;
- };
-
- template <typename Ty>
- inline Ty* pointer(const Ty&)
- {
- return 0;
- }
-
- template <typename Ty>
- inline Container<Ty> containerNew(const Ty& _container)
- {
- return Container<Ty>(_container);
- }
-
- template <typename Ty>
- inline const Container<Ty>* container(const ContainerBase* _base, const Ty*)
- {
- return static_cast<const Container<Ty>*>(_base);
- }
- } // namespace foreach_ns
-
-#define foreach(_variable, _container) \
- for (const bx::foreach_ns::ContainerBase &__temp_container__ = bx::foreach_ns::containerNew(_container); \
- bx::foreach_ns::container(&__temp_container__, true ? 0 : bx::foreach_ns::pointer(_container) )->condition(); \
- ++bx::foreach_ns::container(&__temp_container__, true ? 0 : bx::foreach_ns::pointer(_container) )->m_it) \
- for (_variable = *container(&__temp_container__, true ? 0 : bx::foreach_ns::pointer(_container) )->m_it; \
- bx::foreach_ns::container(&__temp_container__, true ? 0 : bx::foreach_ns::pointer(_container) )->m_break; \
- --bx::foreach_ns::container(&__temp_container__, true ? 0 : bx::foreach_ns::pointer(_container) )->m_break)
-
-} // namespace bx
-
-#endif // BX_FOREACH_H_HEADER_GUARD
diff --git a/3rdparty/bx/include/bx/fpumath.h b/3rdparty/bx/include/bx/fpumath.h
index c7438eb3105..4c04eb6dc52 100644
--- a/3rdparty/bx/include/bx/fpumath.h
+++ b/3rdparty/bx/include/bx/fpumath.h
@@ -14,11 +14,13 @@
namespace bx
{
- static const float pi = 3.14159265358979323846f;
- static const float invPi = 1.0f/3.14159265358979323846f;
- static const float piHalf = 1.57079632679489661923f;
- static const float sqrt2 = 1.41421356237309504880f;
+ extern const float pi;
+ extern const float invPi;
+ extern const float piHalf;
+ extern const float sqrt2;
+ extern const float huge;
+ ///
struct Handness
{
enum Enum
@@ -28,6 +30,7 @@ namespace bx
};
};
+ ///
struct NearFar
{
enum Enum
@@ -37,1425 +40,436 @@ namespace bx
};
};
- inline float toRad(float _deg)
- {
- return _deg * pi / 180.0f;
- }
-
- inline float toDeg(float _rad)
- {
- return _rad * 180.0f / pi;
- }
-
- inline float ffloor(float _f)
- {
- return floorf(_f);
- }
-
- inline float fceil(float _f)
- {
- return ceilf(_f);
- }
-
- inline float fround(float _f)
- {
- return ffloor(_f + 0.5f);
- }
-
- inline float fmin(float _a, float _b)
- {
- return _a < _b ? _a : _b;
- }
+ ///
+ float toRad(float _deg);
- inline float fmax(float _a, float _b)
- {
- return _a > _b ? _a : _b;
- }
+ ///
+ float toDeg(float _rad);
- inline float fmin3(float _a, float _b, float _c)
- {
- return fmin(_a, fmin(_b, _c) );
- }
+ ///
+ uint32_t floatToBits(float _a);
- inline float fmax3(float _a, float _b, float _c)
- {
- return fmax(_a, fmax(_b, _c) );
- }
+ ///
+ float bitsToFloat(uint32_t _a);
- inline float fclamp(float _a, float _min, float _max)
- {
- return fmin(fmax(_a, _min), _max);
- }
+ ///
+ uint64_t doubleToBits(double _a);
- inline float fsaturate(float _a)
- {
- return fclamp(_a, 0.0f, 1.0f);
- }
+ ///
+ double bitsToDouble(uint64_t _a);
- inline float flerp(float _a, float _b, float _t)
- {
- return _a + (_b - _a) * _t;
- }
+ ///
+ bool isNan(float _f);
- inline float fsign(float _a)
- {
- return _a < 0.0f ? -1.0f : 1.0f;
- }
+ ///
+ bool isNan(double _f);
- inline float fabsolute(float _a)
- {
- return fabsf(_a);
- }
+ ///
+ bool isFinite(float _f);
- inline float fsq(float _a)
- {
- return _a * _a;
- }
-
- inline float fsin(float _a)
- {
- return sinf(_a);
- }
+ ///
+ bool isFinite(double _f);
- inline float fasin(float _a)
- {
- return asinf(_a);
- }
+ ///
+ bool isInfinite(float _f);
- inline float fcos(float _a)
- {
- return cosf(_a);
- }
+ ///
+ bool isInfinite(double _f);
- inline float facos(float _a)
- {
- return acosf(_a);
- }
+ ///
+ float ffloor(float _f);
- inline float fpow(float _a, float _b)
- {
- return powf(_a, _b);
- }
+ ///
+ float fceil(float _f);
- inline float fexp2(float _a)
- {
- return fpow(2.0f, _a);
- }
+ ///
+ float fround(float _f);
- inline float flog(float _a)
- {
- return logf(_a);
- }
+ ///
+ float fmin(float _a, float _b);
- inline float flog2(float _a)
- {
- return flog(_a) * 1.442695041f;
- }
+ ///
+ float fmax(float _a, float _b);
- inline float fsqrt(float _a)
- {
- return sqrtf(_a);
- }
+ ///
+ float fmin3(float _a, float _b, float _c);
- inline float frsqrt(float _a)
- {
- return 1.0f/fsqrt(_a);
- }
+ ///
+ float fmax3(float _a, float _b, float _c);
- inline float ffract(float _a)
- {
- return _a - floorf(_a);
- }
+ ///
+ float fclamp(float _a, float _min, float _max);
- inline float fmod(float _a, float _b)
- {
- return fmodf(_a, _b);
- }
+ ///
+ float fsaturate(float _a);
- inline bool fequal(float _a, float _b, float _epsilon)
- {
- // http://realtimecollisiondetection.net/blog/?p=89
- const float lhs = fabsolute(_a - _b);
- const float rhs = _epsilon * fmax3(1.0f, fabsolute(_a), fabsolute(_b) );
- return lhs <= rhs;
- }
+ ///
+ float flerp(float _a, float _b, float _t);
- inline bool fequal(const float* __restrict _a, const float* __restrict _b, uint32_t _num, float _epsilon)
- {
- bool equal = fequal(_a[0], _b[0], _epsilon);
- for (uint32_t ii = 1; equal && ii < _num; ++ii)
- {
- equal = fequal(_a[ii], _b[ii], _epsilon);
- }
- return equal;
- }
+ ///
+ float fsign(float _a);
- inline float fwrap(float _a, float _wrap)
- {
- const float mod = fmod(_a, _wrap);
- const float result = mod < 0.0f ? _wrap + mod : mod;
- return result;
- }
+ ///
+ float fabsolute(float _a);
- inline float fstep(float _edge, float _a)
- {
- return _a < _edge ? 0.0f : 1.0f;
- }
+ ///
+ float fsq(float _a);
- inline float fpulse(float _a, float _start, float _end)
- {
- return fstep(_a, _start) - fstep(_a, _end);
- }
+ ///
+ float fsin(float _a);
- inline float fsmoothstep(float _a)
- {
- return fsq(_a)*(3.0f - 2.0f*_a);
- }
+ ///
+ float fasin(float _a);
- // References:
- // - Bias And Gain Are Your Friend
- // http://blog.demofox.org/2012/09/24/bias-and-gain-are-your-friend/
- // - http://demofox.org/biasgain.html
- inline float fbias(float _time, float _bias)
- {
- return _time / ( ( (1.0f/_bias - 2.0f)*(1.0f - _time) ) + 1.0f);
- }
+ ///
+ float fcos(float _a);
- inline float fgain(float _time, float _gain)
- {
- if (_time < 0.5f)
- {
- return fbias(_time * 2.0f, _gain) * 0.5f;
- }
+ ///
+ float facos(float _a);
- return fbias(_time * 2.0f - 1.0f, 1.0f - _gain) * 0.5f + 0.5f;
- }
+ ///
+ float fatan2(float _y, float _x);
- inline void vec3Move(float* __restrict _result, const float* __restrict _a)
- {
- _result[0] = _a[0];
- _result[1] = _a[1];
- _result[2] = _a[2];
- }
+ ///
+ float fpow(float _a, float _b);
- inline void vec3Abs(float* __restrict _result, const float* __restrict _a)
- {
- _result[0] = fabsolute(_a[0]);
- _result[1] = fabsolute(_a[1]);
- _result[2] = fabsolute(_a[2]);
- }
+ ///
+ float fexp2(float _a);
- inline void vec3Neg(float* __restrict _result, const float* __restrict _a)
- {
- _result[0] = -_a[0];
- _result[1] = -_a[1];
- _result[2] = -_a[2];
- }
+ ///
+ float flog(float _a);
- inline void vec3Add(float* __restrict _result, const float* __restrict _a, const float* __restrict _b)
- {
- _result[0] = _a[0] + _b[0];
- _result[1] = _a[1] + _b[1];
- _result[2] = _a[2] + _b[2];
- }
+ ///
+ float flog2(float _a);
- inline void vec3Add(float* __restrict _result, const float* __restrict _a, float _b)
- {
- _result[0] = _a[0] + _b;
- _result[1] = _a[1] + _b;
- _result[2] = _a[2] + _b;
- }
+ ///
+ float fsqrt(float _a);
- inline void vec3Sub(float* __restrict _result, const float* __restrict _a, const float* __restrict _b)
- {
- _result[0] = _a[0] - _b[0];
- _result[1] = _a[1] - _b[1];
- _result[2] = _a[2] - _b[2];
- }
+ ///
+ float frsqrt(float _a);
- inline void vec3Sub(float* __restrict _result, const float* __restrict _a, float _b)
- {
- _result[0] = _a[0] - _b;
- _result[1] = _a[1] - _b;
- _result[2] = _a[2] - _b;
- }
+ ///
+ float ffract(float _a);
- inline void vec3Mul(float* __restrict _result, const float* __restrict _a, const float* __restrict _b)
- {
- _result[0] = _a[0] * _b[0];
- _result[1] = _a[1] * _b[1];
- _result[2] = _a[2] * _b[2];
- }
+ ///
+ float fmod(float _a, float _b);
- inline void vec3Mul(float* __restrict _result, const float* __restrict _a, float _b)
- {
- _result[0] = _a[0] * _b;
- _result[1] = _a[1] * _b;
- _result[2] = _a[2] * _b;
- }
+ ///
+ bool fequal(float _a, float _b, float _epsilon);
- inline float vec3Dot(const float* __restrict _a, const float* __restrict _b)
- {
- return _a[0]*_b[0] + _a[1]*_b[1] + _a[2]*_b[2];
- }
+ ///
+ bool fequal(const float* __restrict _a, const float* __restrict _b, uint32_t _num, float _epsilon);
- inline void vec3Cross(float* __restrict _result, const float* __restrict _a, const float* __restrict _b)
- {
- _result[0] = _a[1]*_b[2] - _a[2]*_b[1];
- _result[1] = _a[2]*_b[0] - _a[0]*_b[2];
- _result[2] = _a[0]*_b[1] - _a[1]*_b[0];
- }
+ ///
+ float fwrap(float _a, float _wrap);
- inline float vec3Length(const float* _a)
- {
- return fsqrt(vec3Dot(_a, _a) );
- }
+ ///
+ float fstep(float _edge, float _a);
- inline void vec3Lerp(float* __restrict _result, const float* __restrict _a, const float* __restrict _b, float _t)
- {
- _result[0] = flerp(_a[0], _b[0], _t);
- _result[1] = flerp(_a[1], _b[1], _t);
- _result[2] = flerp(_a[2], _b[2], _t);
- }
+ ///
+ float fpulse(float _a, float _start, float _end);
- inline void vec3Lerp(float* __restrict _result, const float* __restrict _a, const float* __restrict _b, const float* __restrict _c)
- {
- _result[0] = flerp(_a[0], _b[0], _c[0]);
- _result[1] = flerp(_a[1], _b[1], _c[1]);
- _result[2] = flerp(_a[2], _b[2], _c[2]);
- }
+ ///
+ float fsmoothstep(float _a);
- inline float vec3Norm(float* __restrict _result, const float* __restrict _a)
- {
- const float len = vec3Length(_a);
- const float invLen = 1.0f/len;
- _result[0] = _a[0] * invLen;
- _result[1] = _a[1] * invLen;
- _result[2] = _a[2] * invLen;
- return len;
- }
-
- inline void vec3Min(float* __restrict _result, const float* __restrict _a, const float* __restrict _b)
- {
- _result[0] = fmin(_a[0], _b[0]);
- _result[1] = fmin(_a[1], _b[1]);
- _result[2] = fmin(_a[2], _b[2]);
- }
+ // References:
+ // - Bias And Gain Are Your Friend
+ // http://blog.demofox.org/2012/09/24/bias-and-gain-are-your-friend/
+ // - http://demofox.org/biasgain.html
+ ///
+ float fbias(float _time, float _bias);
- inline void vec3Max(float* __restrict _result, const float* __restrict _a, const float* __restrict _b)
- {
- _result[0] = fmax(_a[0], _b[0]);
- _result[1] = fmax(_a[1], _b[1]);
- _result[2] = fmax(_a[2], _b[2]);
- }
+ ///
+ float fgain(float _time, float _gain);
- inline void vec3Rcp(float* __restrict _result, const float* __restrict _a)
- {
- _result[0] = 1.0f / _a[0];
- _result[1] = 1.0f / _a[1];
- _result[2] = 1.0f / _a[2];
- }
+ ///
+ void vec3Move(float* __restrict _result, const float* __restrict _a);
- /// Calculate tangent frame from normal.
- inline void vec3TangentFrame(const float* __restrict _n, float* __restrict _t, float* __restrict _b)
- {
- const float nx = _n[0];
- const float ny = _n[1];
- const float nz = _n[2];
+ ///
+ void vec3Abs(float* __restrict _result, const float* __restrict _a);
- if (bx::fabsolute(nx) > bx::fabsolute(nz) )
- {
- float invLen = 1.0f / bx::fsqrt(nx*nx + nz*nz);
- _t[0] = -nz * invLen;
- _t[1] = 0.0f;
- _t[2] = nx * invLen;
- }
- else
- {
- float invLen = 1.0f / bx::fsqrt(ny*ny + nz*nz);
- _t[0] = 0.0f;
- _t[1] = nz * invLen;
- _t[2] = -ny * invLen;
- }
+ ///
+ void vec3Neg(float* __restrict _result, const float* __restrict _a);
- bx::vec3Cross(_b, _n, _t);
- }
+ ///
+ void vec3Add(float* __restrict _result, const float* __restrict _a, const float* __restrict _b);
- /// Calculate tangent frame from normal and angle.
- inline void vec3TangentFrame(const float* __restrict _n, float* __restrict _t, float* __restrict _b, float _angle)
- {
- vec3TangentFrame(_n, _t, _b);
+ ///
+ void vec3Add(float* __restrict _result, const float* __restrict _a, float _b);
- const float sa = fsin(_angle);
- const float ca = fcos(_angle);
+ ///
+ void vec3Sub(float* __restrict _result, const float* __restrict _a, const float* __restrict _b);
- _t[0] = -sa * _b[0] + ca * _t[0];
- _t[1] = -sa * _b[1] + ca * _t[1];
- _t[2] = -sa * _b[2] + ca * _t[2];
+ ///
+ void vec3Sub(float* __restrict _result, const float* __restrict _a, float _b);
- bx::vec3Cross(_b, _n, _t);
- }
+ ///
+ void vec3Mul(float* __restrict _result, const float* __restrict _a, const float* __restrict _b);
- inline void quatIdentity(float* _result)
- {
- _result[0] = 0.0f;
- _result[1] = 0.0f;
- _result[2] = 0.0f;
- _result[3] = 1.0f;
- }
+ ///
+ void vec3Mul(float* __restrict _result, const float* __restrict _a, float _b);
- inline void quatMove(float* __restrict _result, const float* __restrict _a)
- {
- _result[0] = _a[0];
- _result[1] = _a[1];
- _result[2] = _a[2];
- _result[3] = _a[3];
- }
+ ///
+ float vec3Dot(const float* __restrict _a, const float* __restrict _b);
- inline void quatMulXYZ(float* __restrict _result, const float* __restrict _qa, const float* __restrict _qb)
- {
- const float ax = _qa[0];
- const float ay = _qa[1];
- const float az = _qa[2];
- const float aw = _qa[3];
-
- const float bx = _qb[0];
- const float by = _qb[1];
- const float bz = _qb[2];
- const float bw = _qb[3];
-
- _result[0] = aw * bx + ax * bw + ay * bz - az * by;
- _result[1] = aw * by - ax * bz + ay * bw + az * bx;
- _result[2] = aw * bz + ax * by - ay * bx + az * bw;
- }
-
- inline void quatMul(float* __restrict _result, const float* __restrict _qa, const float* __restrict _qb)
- {
- const float ax = _qa[0];
- const float ay = _qa[1];
- const float az = _qa[2];
- const float aw = _qa[3];
-
- const float bx = _qb[0];
- const float by = _qb[1];
- const float bz = _qb[2];
- const float bw = _qb[3];
-
- _result[0] = aw * bx + ax * bw + ay * bz - az * by;
- _result[1] = aw * by - ax * bz + ay * bw + az * bx;
- _result[2] = aw * bz + ax * by - ay * bx + az * bw;
- _result[3] = aw * bw - ax * bx - ay * by - az * bz;
- }
-
- inline void quatInvert(float* __restrict _result, const float* __restrict _quat)
- {
- _result[0] = -_quat[0];
- _result[1] = -_quat[1];
- _result[2] = -_quat[2];
- _result[3] = _quat[3];
- }
+ ///
+ void vec3Cross(float* __restrict _result, const float* __restrict _a, const float* __restrict _b);
- inline float quatDot(const float* __restrict _a, const float* __restrict _b)
- {
- return _a[0]*_b[0]
- + _a[1]*_b[1]
- + _a[2]*_b[2]
- + _a[3]*_b[3]
- ;
- }
-
- inline void quatNorm(float* __restrict _result, const float* __restrict _quat)
- {
- const float norm = quatDot(_quat, _quat);
- if (0.0f < norm)
- {
- const float invNorm = 1.0f / fsqrt(norm);
- _result[0] = _quat[0] * invNorm;
- _result[1] = _quat[1] * invNorm;
- _result[2] = _quat[2] * invNorm;
- _result[3] = _quat[3] * invNorm;
- }
- else
- {
- quatIdentity(_result);
- }
- }
+ ///
+ float vec3Length(const float* _a);
- inline void quatToEuler(float* __restrict _result, const float* __restrict _quat)
- {
- const float x = _quat[0];
- const float y = _quat[1];
- const float z = _quat[2];
- const float w = _quat[3];
+ ///
+ void vec3Lerp(float* __restrict _result, const float* __restrict _a, const float* __restrict _b, float _t);
- const float yy = y * y;
- const float zz = z * z;
+ ///
+ void vec3Lerp(float* __restrict _result, const float* __restrict _a, const float* __restrict _b, const float* __restrict _c);
- const float xx = x * x;
- _result[0] = atan2f(2.0f * (x * w - y * z), 1.0f - 2.0f * (xx + zz) );
- _result[1] = atan2f(2.0f * (y * w + x * z), 1.0f - 2.0f * (yy + zz) );
- _result[2] = asinf (2.0f * (x * y + z * w) );
- }
+ ///
+ float vec3Norm(float* __restrict _result, const float* __restrict _a);
- inline void quatRotateAxis(float* __restrict _result, const float* _axis, float _angle)
- {
- const float ha = _angle * 0.5f;
- const float ca = fcos(ha);
- const float sa = fsin(ha);
- _result[0] = _axis[0] * sa;
- _result[1] = _axis[1] * sa;
- _result[2] = _axis[2] * sa;
- _result[3] = ca;
- }
-
- inline void quatRotateX(float* _result, float _ax)
- {
- const float hx = _ax * 0.5f;
- const float cx = fcos(hx);
- const float sx = fsin(hx);
- _result[0] = sx;
- _result[1] = 0.0f;
- _result[2] = 0.0f;
- _result[3] = cx;
- }
-
- inline void quatRotateY(float* _result, float _ay)
- {
- const float hy = _ay * 0.5f;
- const float cy = fcos(hy);
- const float sy = fsin(hy);
- _result[0] = 0.0f;
- _result[1] = sy;
- _result[2] = 0.0f;
- _result[3] = cy;
- }
-
- inline void quatRotateZ(float* _result, float _az)
- {
- const float hz = _az * 0.5f;
- const float cz = fcos(hz);
- const float sz = fsin(hz);
- _result[0] = 0.0f;
- _result[1] = 0.0f;
- _result[2] = sz;
- _result[3] = cz;
- }
-
- inline void vec3MulQuat(float* __restrict _result, const float* __restrict _vec, const float* __restrict _quat)
- {
- float tmp0[4];
- quatInvert(tmp0, _quat);
+ ///
+ void vec3Min(float* __restrict _result, const float* __restrict _a, const float* __restrict _b);
- float qv[4];
- qv[0] = _vec[0];
- qv[1] = _vec[1];
- qv[2] = _vec[2];
- qv[3] = 0.0f;
+ ///
+ void vec3Max(float* __restrict _result, const float* __restrict _a, const float* __restrict _b);
- float tmp1[4];
- quatMul(tmp1, tmp0, qv);
+ ///
+ void vec3Rcp(float* __restrict _result, const float* __restrict _a);
- quatMulXYZ(_result, tmp1, _quat);
- }
+ /// Calculate tangent frame from normal.
+ ///
+ void vec3TangentFrame(const float* __restrict _n, float* __restrict _t, float* __restrict _b);
- inline void mtxIdentity(float* _result)
- {
- memset(_result, 0, sizeof(float)*16);
- _result[0] = _result[5] = _result[10] = _result[15] = 1.0f;
- }
+ /// Calculate tangent frame from normal and angle.
+ ///
+ void vec3TangentFrame(const float* __restrict _n, float* __restrict _t, float* __restrict _b, float _angle);
- inline void mtxTranslate(float* _result, float _tx, float _ty, float _tz)
- {
- mtxIdentity(_result);
- _result[12] = _tx;
- _result[13] = _ty;
- _result[14] = _tz;
- }
+ ///
+ void quatIdentity(float* _result);
- inline void mtxScale(float* _result, float _sx, float _sy, float _sz)
- {
- memset(_result, 0, sizeof(float) * 16);
- _result[0] = _sx;
- _result[5] = _sy;
- _result[10] = _sz;
- _result[15] = 1.0f;
- }
-
- inline void mtxScale(float* _result, float _scale)
- {
- mtxScale(_result, _scale, _scale, _scale);
- }
+ ///
+ void quatMove(float* __restrict _result, const float* __restrict _a);
- inline void mtxFromNormal(float* __restrict _result, const float* __restrict _normal, float _scale, const float* __restrict _pos)
- {
- float tangent[3];
- float bitangent[3];
- vec3TangentFrame(_normal, tangent, bitangent);
-
- vec3Mul(&_result[ 0], bitangent, _scale);
- vec3Mul(&_result[ 4], _normal, _scale);
- vec3Mul(&_result[ 8], tangent, _scale);
-
- _result[ 3] = 0.0f;
- _result[ 7] = 0.0f;
- _result[11] = 0.0f;
- _result[12] = _pos[0];
- _result[13] = _pos[1];
- _result[14] = _pos[2];
- _result[15] = 1.0f;
- }
-
- inline void mtxFromNormal(float* __restrict _result, const float* __restrict _normal, float _scale, const float* __restrict _pos, float _angle)
- {
- float tangent[3];
- float bitangent[3];
- vec3TangentFrame(_normal, tangent, bitangent, _angle);
-
- vec3Mul(&_result[ 0], bitangent, _scale);
- vec3Mul(&_result[ 4], _normal, _scale);
- vec3Mul(&_result[ 8], tangent, _scale);
-
- _result[ 3] = 0.0f;
- _result[ 7] = 0.0f;
- _result[11] = 0.0f;
- _result[12] = _pos[0];
- _result[13] = _pos[1];
- _result[14] = _pos[2];
- _result[15] = 1.0f;
- }
-
- inline void mtxQuat(float* __restrict _result, const float* __restrict _quat)
- {
- const float x = _quat[0];
- const float y = _quat[1];
- const float z = _quat[2];
- const float w = _quat[3];
-
- const float x2 = x + x;
- const float y2 = y + y;
- const float z2 = z + z;
- const float x2x = x2 * x;
- const float x2y = x2 * y;
- const float x2z = x2 * z;
- const float x2w = x2 * w;
- const float y2y = y2 * y;
- const float y2z = y2 * z;
- const float y2w = y2 * w;
- const float z2z = z2 * z;
- const float z2w = z2 * w;
-
- _result[ 0] = 1.0f - (y2y + z2z);
- _result[ 1] = x2y - z2w;
- _result[ 2] = x2z + y2w;
- _result[ 3] = 0.0f;
-
- _result[ 4] = x2y + z2w;
- _result[ 5] = 1.0f - (x2x + z2z);
- _result[ 6] = y2z - x2w;
- _result[ 7] = 0.0f;
-
- _result[ 8] = x2z - y2w;
- _result[ 9] = y2z + x2w;
- _result[10] = 1.0f - (x2x + y2y);
- _result[11] = 0.0f;
-
- _result[12] = 0.0f;
- _result[13] = 0.0f;
- _result[14] = 0.0f;
- _result[15] = 1.0f;
- }
-
- inline void mtxQuatTranslation(float* __restrict _result, const float* __restrict _quat, const float* __restrict _translation)
- {
- mtxQuat(_result, _quat);
- _result[12] = -(_result[0]*_translation[0] + _result[4]*_translation[1] + _result[ 8]*_translation[2]);
- _result[13] = -(_result[1]*_translation[0] + _result[5]*_translation[1] + _result[ 9]*_translation[2]);
- _result[14] = -(_result[2]*_translation[0] + _result[6]*_translation[1] + _result[10]*_translation[2]);
- }
+ ///
+ void quatMulXYZ(float* __restrict _result, const float* __restrict _qa, const float* __restrict _qb);
- inline void mtxQuatTranslationHMD(float* __restrict _result, const float* __restrict _quat, const float* __restrict _translation)
- {
- float quat[4];
- quat[0] = -_quat[0];
- quat[1] = -_quat[1];
- quat[2] = _quat[2];
- quat[3] = _quat[3];
- mtxQuatTranslation(_result, quat, _translation);
- }
-
- inline void mtxLookAt_Impl(float* __restrict _result, const float* __restrict _eye, const float* __restrict _view, const float* __restrict _up = NULL)
- {
- float up[3] = { 0.0f, 1.0f, 0.0f };
- if (NULL != _up)
- {
- up[0] = _up[0];
- up[1] = _up[1];
- up[2] = _up[2];
- }
+ ///
+ void quatMul(float* __restrict _result, const float* __restrict _qa, const float* __restrict _qb);
- float tmp[4];
- vec3Cross(tmp, up, _view);
+ ///
+ void quatInvert(float* __restrict _result, const float* __restrict _quat);
- float right[4];
- vec3Norm(right, tmp);
+ ///
+ float quatDot(const float* __restrict _a, const float* __restrict _b);
- vec3Cross(up, _view, right);
+ ///
+ void quatNorm(float* __restrict _result, const float* __restrict _quat);
- memset(_result, 0, sizeof(float)*16);
- _result[ 0] = right[0];
- _result[ 1] = up[0];
- _result[ 2] = _view[0];
+ ///
+ void quatToEuler(float* __restrict _result, const float* __restrict _quat);
- _result[ 4] = right[1];
- _result[ 5] = up[1];
- _result[ 6] = _view[1];
+ ///
+ void quatRotateAxis(float* __restrict _result, const float* _axis, float _angle);
- _result[ 8] = right[2];
- _result[ 9] = up[2];
- _result[10] = _view[2];
+ ///
+ void quatRotateX(float* _result, float _ax);
- _result[12] = -vec3Dot(right, _eye);
- _result[13] = -vec3Dot(up, _eye);
- _result[14] = -vec3Dot(_view, _eye);
- _result[15] = 1.0f;
- }
+ ///
+ void quatRotateY(float* _result, float _ay);
- inline void mtxLookAtLh(float* __restrict _result, const float* __restrict _eye, const float* __restrict _at, const float* __restrict _up = NULL)
- {
- float tmp[4];
- vec3Sub(tmp, _at, _eye);
+ ///
+ void quatRotateZ(float* _result, float _az);
- float view[4];
- vec3Norm(view, tmp);
+ ///
+ void vec3MulQuat(float* __restrict _result, const float* __restrict _vec, const float* __restrict _quat);
- mtxLookAt_Impl(_result, _eye, view, _up);
- }
+ ///
+ void mtxIdentity(float* _result);
- inline void mtxLookAtRh(float* __restrict _result, const float* __restrict _eye, const float* __restrict _at, const float* __restrict _up = NULL)
- {
- float tmp[4];
- vec3Sub(tmp, _eye, _at);
+ ///
+ void mtxTranslate(float* _result, float _tx, float _ty, float _tz);
- float view[4];
- vec3Norm(view, tmp);
+ ///
+ void mtxScale(float* _result, float _sx, float _sy, float _sz);
- mtxLookAt_Impl(_result, _eye, view, _up);
- }
+ ///
+ void mtxScale(float* _result, float _scale);
- inline void mtxLookAt(float* __restrict _result, const float* __restrict _eye, const float* __restrict _at, const float* __restrict _up = NULL)
- {
- mtxLookAtLh(_result, _eye, _at, _up);
- }
+ ///
+ void mtxFromNormal(float* __restrict _result, const float* __restrict _normal, float _scale, const float* __restrict _pos);
- template <Handness::Enum HandnessT>
- inline void mtxProjXYWH(float* _result, float _x, float _y, float _width, float _height, float _near, float _far, bool _oglNdc = false)
- {
- const float diff = _far-_near;
- const float aa = _oglNdc ? (_far+_near)/diff : _far/diff;
- const float bb = _oglNdc ? (2.0f*_far*_near)/diff : _near*aa;
-
- memset(_result, 0, sizeof(float)*16);
- _result[ 0] = _width;
- _result[ 5] = _height;
- _result[ 8] = (Handness::Right == HandnessT) ? _x : -_x;
- _result[ 9] = (Handness::Right == HandnessT) ? _y : -_y;
- _result[10] = (Handness::Right == HandnessT) ? -aa : aa;
- _result[11] = (Handness::Right == HandnessT) ? -1.0f : 1.0f;
- _result[14] = -bb;
- }
-
- template <Handness::Enum HandnessT>
- inline void mtxProj_impl(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, float _far, bool _oglNdc = false)
- {
- const float invDiffRl = 1.0f/(_rt - _lt);
- const float invDiffUd = 1.0f/(_ut - _dt);
- const float width = 2.0f*_near * invDiffRl;
- const float height = 2.0f*_near * invDiffUd;
- const float xx = (_rt + _lt) * invDiffRl;
- const float yy = (_ut + _dt) * invDiffUd;
- mtxProjXYWH<HandnessT>(_result, xx, yy, width, height, _near, _far, _oglNdc);
- }
-
- template <Handness::Enum HandnessT>
- inline void mtxProj_impl(float* _result, const float _fov[4], float _near, float _far, bool _oglNdc = false)
- {
- mtxProj_impl<HandnessT>(_result, _fov[0], _fov[1], _fov[2], _fov[3], _near, _far, _oglNdc);
- }
+ ///
+ void mtxFromNormal(float* __restrict _result, const float* __restrict _normal, float _scale, const float* __restrict _pos, float _angle);
- template <Handness::Enum HandnessT>
- inline void mtxProj_impl(float* _result, float _fovy, float _aspect, float _near, float _far, bool _oglNdc = false)
- {
- const float height = 1.0f/tanf(toRad(_fovy)*0.5f);
- const float width = height * 1.0f/_aspect;
- mtxProjXYWH<HandnessT>(_result, 0.0f, 0.0f, width, height, _near, _far, _oglNdc);
- }
+ ///
+ void mtxQuat(float* __restrict _result, const float* __restrict _quat);
- inline void mtxProj(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, float _far, bool _oglNdc = false)
- {
- mtxProj_impl<Handness::Left>(_result, _ut, _dt, _lt, _rt, _near, _far, _oglNdc);
- }
+ ///
+ void mtxQuatTranslation(float* __restrict _result, const float* __restrict _quat, const float* __restrict _translation);
- inline void mtxProj(float* _result, const float _fov[4], float _near, float _far, bool _oglNdc = false)
- {
- mtxProj_impl<Handness::Left>(_result, _fov, _near, _far, _oglNdc);
- }
+ ///
+ void mtxQuatTranslationHMD(float* __restrict _result, const float* __restrict _quat, const float* __restrict _translation);
- inline void mtxProj(float* _result, float _fovy, float _aspect, float _near, float _far, bool _oglNdc = false)
- {
- mtxProj_impl<Handness::Left>(_result, _fovy, _aspect, _near, _far, _oglNdc);
- }
+ ///
+ void mtxLookAtLh(float* __restrict _result, const float* __restrict _eye, const float* __restrict _at, const float* __restrict _up = NULL);;
- inline void mtxProjLh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, float _far, bool _oglNdc = false)
- {
- mtxProj_impl<Handness::Left>(_result, _ut, _dt, _lt, _rt, _near, _far, _oglNdc);
- }
+ ///
+ void mtxLookAtRh(float* __restrict _result, const float* __restrict _eye, const float* __restrict _at, const float* __restrict _up = NULL);
- inline void mtxProjLh(float* _result, const float _fov[4], float _near, float _far, bool _oglNdc = false)
- {
- mtxProj_impl<Handness::Left>(_result, _fov, _near, _far, _oglNdc);
- }
+ ///
+ void mtxLookAt(float* __restrict _result, const float* __restrict _eye, const float* __restrict _at, const float* __restrict _up = NULL);
- inline void mtxProjLh(float* _result, float _fovy, float _aspect, float _near, float _far, bool _oglNdc = false)
- {
- mtxProj_impl<Handness::Left>(_result, _fovy, _aspect, _near, _far, _oglNdc);
- }
+ ///
+ void mtxProj(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, float _far, bool _oglNdc = false);
- inline void mtxProjRh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, float _far, bool _oglNdc = false)
- {
- mtxProj_impl<Handness::Right>(_result, _ut, _dt, _lt, _rt, _near, _far, _oglNdc);
- }
+ ///
+ void mtxProj(float* _result, const float _fov[4], float _near, float _far, bool _oglNdc = false);
- inline void mtxProjRh(float* _result, const float _fov[4], float _near, float _far, bool _oglNdc = false)
- {
- mtxProj_impl<Handness::Right>(_result, _fov, _near, _far, _oglNdc);
- }
+ ///
+ void mtxProj(float* _result, float _fovy, float _aspect, float _near, float _far, bool _oglNdc = false);
- inline void mtxProjRh(float* _result, float _fovy, float _aspect, float _near, float _far, bool _oglNdc = false)
- {
- mtxProj_impl<Handness::Right>(_result, _fovy, _aspect, _near, _far, _oglNdc);
- }
+ ///
+ void mtxProjLh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, float _far, bool _oglNdc = false);
- template <NearFar::Enum NearFarT, Handness::Enum HandnessT>
- inline void mtxProjInfXYWH(float* _result, float _x, float _y, float _width, float _height, float _near, bool _oglNdc = false)
- {
- float aa;
- float bb;
- if (BX_ENABLED(NearFar::Reverse == NearFarT) )
- {
- aa = _oglNdc ? -1.0f : 0.0f;
- bb = _oglNdc ? -2.0f*_near : -_near;
- }
- else
- {
- aa = 1.0f;
- bb = _oglNdc ? 2.0f*_near : _near;
- }
-
- memset(_result, 0, sizeof(float)*16);
- _result[ 0] = _width;
- _result[ 5] = _height;
- _result[ 8] = (Handness::Right == HandnessT) ? _x : -_x;
- _result[ 9] = (Handness::Right == HandnessT) ? _y : -_y;
- _result[10] = (Handness::Right == HandnessT) ? -aa : aa;
- _result[11] = (Handness::Right == HandnessT) ? -1.0f : 1.0f;
- _result[14] = -bb;
- }
-
- template <NearFar::Enum NearFarT, Handness::Enum HandnessT>
- inline void mtxProjInf_impl(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc = false)
- {
- const float invDiffRl = 1.0f/(_rt - _lt);
- const float invDiffUd = 1.0f/(_ut - _dt);
- const float width = 2.0f*_near * invDiffRl;
- const float height = 2.0f*_near * invDiffUd;
- const float xx = (_rt + _lt) * invDiffRl;
- const float yy = (_ut + _dt) * invDiffUd;
- mtxProjInfXYWH<NearFarT,HandnessT>(_result, xx, yy, width, height, _near, _oglNdc);
- }
-
- template <NearFar::Enum NearFarT, Handness::Enum HandnessT>
- inline void mtxProjInf_impl(float* _result, const float _fov[4], float _near, bool _oglNdc = false)
- {
- mtxProjInf_impl<NearFarT,HandnessT>(_result, _fov[0], _fov[1], _fov[2], _fov[3], _near, _oglNdc);
- }
+ ///
+ void mtxProjLh(float* _result, const float _fov[4], float _near, float _far, bool _oglNdc = false);
- template <NearFar::Enum NearFarT, Handness::Enum HandnessT>
- inline void mtxProjInf_impl(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc = false)
- {
- const float height = 1.0f/tanf(toRad(_fovy)*0.5f);
- const float width = height * 1.0f/_aspect;
- mtxProjInfXYWH<NearFarT,HandnessT>(_result, 0.0f, 0.0f, width, height, _near, _oglNdc);
- }
+ ///
+ void mtxProjLh(float* _result, float _fovy, float _aspect, float _near, float _far, bool _oglNdc = false);
- inline void mtxProjInf(float* _result, const float _fov[4], float _near, bool _oglNdc = false)
- {
- mtxProjInf_impl<NearFar::Default,Handness::Left>(_result, _fov, _near, _oglNdc);
- }
+ ///
+ void mtxProjRh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, float _far, bool _oglNdc = false);
- inline void mtxProjInf(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc = false)
- {
- mtxProjInf_impl<NearFar::Default,Handness::Left>(_result, _ut, _dt, _lt, _rt, _near, _oglNdc);
- }
+ ///
+ void mtxProjRh(float* _result, const float _fov[4], float _near, float _far, bool _oglNdc = false);
- inline void mtxProjInf(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc = false)
- {
- mtxProjInf_impl<NearFar::Default,Handness::Left>(_result, _fovy, _aspect, _near, _oglNdc);
- }
+ ///
+ void mtxProjRh(float* _result, float _fovy, float _aspect, float _near, float _far, bool _oglNdc = false);
- inline void mtxProjInfLh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc = false)
- {
- mtxProjInf_impl<NearFar::Default,Handness::Left>(_result, _ut, _dt, _lt, _rt, _near, _oglNdc);
- }
+ ///
+ void mtxProjInf(float* _result, const float _fov[4], float _near, bool _oglNdc = false);
- inline void mtxProjInfLh(float* _result, const float _fov[4], float _near, bool _oglNdc = false)
- {
- mtxProjInf_impl<NearFar::Default,Handness::Left>(_result, _fov, _near, _oglNdc);
- }
+ ///
+ void mtxProjInf(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc = false);
- inline void mtxProjInfLh(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc = false)
- {
- mtxProjInf_impl<NearFar::Default,Handness::Left>(_result, _fovy, _aspect, _near, _oglNdc);
- }
+ ///
+ void mtxProjInf(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc = false);
- inline void mtxProjInfRh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc = false)
- {
- mtxProjInf_impl<NearFar::Default,Handness::Right>(_result, _ut, _dt, _lt, _rt, _near, _oglNdc);
- }
+ ///
+ void mtxProjInfLh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc = false);
- inline void mtxProjInfRh(float* _result, const float _fov[4], float _near, bool _oglNdc = false)
- {
- mtxProjInf_impl<NearFar::Default,Handness::Right>(_result, _fov, _near, _oglNdc);
- }
+ ///
+ void mtxProjInfLh(float* _result, const float _fov[4], float _near, bool _oglNdc = false);
- inline void mtxProjInfRh(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc = false)
- {
- mtxProjInf_impl<NearFar::Default,Handness::Right>(_result, _fovy, _aspect, _near, _oglNdc);
- }
+ ///
+ void mtxProjInfLh(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc = false);
- inline void mtxProjRevInfLh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc = false)
- {
- mtxProjInf_impl<NearFar::Reverse,Handness::Left>(_result, _ut, _dt, _lt, _rt, _near, _oglNdc);
- }
+ ///
+ void mtxProjInfRh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc = false);
- inline void mtxProjRevInfLh(float* _result, const float _fov[4], float _near, bool _oglNdc = false)
- {
- mtxProjInf_impl<NearFar::Reverse,Handness::Left>(_result, _fov, _near, _oglNdc);
- }
+ ///
+ void mtxProjInfRh(float* _result, const float _fov[4], float _near, bool _oglNdc = false);
- inline void mtxProjRevInfLh(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc = false)
- {
- mtxProjInf_impl<NearFar::Reverse,Handness::Left>(_result, _fovy, _aspect, _near, _oglNdc);
- }
+ ///
+ void mtxProjInfRh(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc = false);
- inline void mtxProjRevInfRh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc = false)
- {
- mtxProjInf_impl<NearFar::Reverse,Handness::Right>(_result, _ut, _dt, _lt, _rt, _near, _oglNdc);
- }
+ ///
+ void mtxProjRevInfLh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc = false);
- inline void mtxProjRevInfRh(float* _result, const float _fov[4], float _near, bool _oglNdc = false)
- {
- mtxProjInf_impl<NearFar::Reverse,Handness::Right>(_result, _fov, _near, _oglNdc);
- }
+ ///
+ void mtxProjRevInfLh(float* _result, const float _fov[4], float _near, bool _oglNdc = false);
- inline void mtxProjRevInfRh(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc = false)
- {
- mtxProjInf_impl<NearFar::Reverse,Handness::Right>(_result, _fovy, _aspect, _near, _oglNdc);
- }
+ ///
+ void mtxProjRevInfLh(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc = false);
- template <Handness::Enum HandnessT>
- inline void mtxOrtho_impl(float* _result, float _left, float _right, float _bottom, float _top, float _near, float _far, float _offset = 0.0f, bool _oglNdc = false)
- {
- const float aa = 2.0f/(_right - _left);
- const float bb = 2.0f/(_top - _bottom);
- const float cc = (_oglNdc ? 2.0f : 1.0f) / (_far - _near);
- const float dd = (_left + _right)/(_left - _right);
- const float ee = (_top + _bottom)/(_bottom - _top);
- const float ff = _oglNdc ? (_near + _far)/(_near - _far) : _near/(_near - _far);
-
- memset(_result, 0, sizeof(float)*16);
- _result[ 0] = aa;
- _result[ 5] = bb;
- _result[10] = (Handness::Right == HandnessT) ? -cc : cc;
- _result[12] = dd + _offset;
- _result[13] = ee;
- _result[14] = ff;
- _result[15] = 1.0f;
- }
-
- inline void mtxOrtho(float* _result, float _left, float _right, float _bottom, float _top, float _near, float _far, float _offset = 0.0f, bool _oglNdc = false)
- {
- mtxOrtho_impl<Handness::Left>(_result, _left, _right, _bottom, _top, _near, _far, _offset, _oglNdc);
- }
+ ///
+ void mtxProjRevInfRh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc = false);
- inline void mtxOrthoLh(float* _result, float _left, float _right, float _bottom, float _top, float _near, float _far, float _offset = 0.0f, bool _oglNdc = false)
- {
- mtxOrtho_impl<Handness::Left>(_result, _left, _right, _bottom, _top, _near, _far, _offset, _oglNdc);
- }
+ ///
+ void mtxProjRevInfRh(float* _result, const float _fov[4], float _near, bool _oglNdc = false);
- inline void mtxOrthoRh(float* _result, float _left, float _right, float _bottom, float _top, float _near, float _far, float _offset = 0.0f, bool _oglNdc = false)
- {
- mtxOrtho_impl<Handness::Right>(_result, _left, _right, _bottom, _top, _near, _far, _offset, _oglNdc);
- }
+ ///
+ void mtxProjRevInfRh(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc = false);
- inline void mtxRotateX(float* _result, float _ax)
- {
- const float sx = fsin(_ax);
- const float cx = fcos(_ax);
-
- memset(_result, 0, sizeof(float)*16);
- _result[ 0] = 1.0f;
- _result[ 5] = cx;
- _result[ 6] = -sx;
- _result[ 9] = sx;
- _result[10] = cx;
- _result[15] = 1.0f;
- }
-
- inline void mtxRotateY(float* _result, float _ay)
- {
- const float sy = fsin(_ay);
- const float cy = fcos(_ay);
-
- memset(_result, 0, sizeof(float)*16);
- _result[ 0] = cy;
- _result[ 2] = sy;
- _result[ 5] = 1.0f;
- _result[ 8] = -sy;
- _result[10] = cy;
- _result[15] = 1.0f;
- }
-
- inline void mtxRotateZ(float* _result, float _az)
- {
- const float sz = fsin(_az);
- const float cz = fcos(_az);
-
- memset(_result, 0, sizeof(float)*16);
- _result[ 0] = cz;
- _result[ 1] = -sz;
- _result[ 4] = sz;
- _result[ 5] = cz;
- _result[10] = 1.0f;
- _result[15] = 1.0f;
- }
-
- inline void mtxRotateXY(float* _result, float _ax, float _ay)
- {
- const float sx = fsin(_ax);
- const float cx = fcos(_ax);
- const float sy = fsin(_ay);
- const float cy = fcos(_ay);
-
- memset(_result, 0, sizeof(float)*16);
- _result[ 0] = cy;
- _result[ 2] = sy;
- _result[ 4] = sx*sy;
- _result[ 5] = cx;
- _result[ 6] = -sx*cy;
- _result[ 8] = -cx*sy;
- _result[ 9] = sx;
- _result[10] = cx*cy;
- _result[15] = 1.0f;
- }
-
- inline void mtxRotateXYZ(float* _result, float _ax, float _ay, float _az)
- {
- const float sx = fsin(_ax);
- const float cx = fcos(_ax);
- const float sy = fsin(_ay);
- const float cy = fcos(_ay);
- const float sz = fsin(_az);
- const float cz = fcos(_az);
-
- memset(_result, 0, sizeof(float)*16);
- _result[ 0] = cy*cz;
- _result[ 1] = -cy*sz;
- _result[ 2] = sy;
- _result[ 4] = cz*sx*sy + cx*sz;
- _result[ 5] = cx*cz - sx*sy*sz;
- _result[ 6] = -cy*sx;
- _result[ 8] = -cx*cz*sy + sx*sz;
- _result[ 9] = cz*sx + cx*sy*sz;
- _result[10] = cx*cy;
- _result[15] = 1.0f;
- }
-
- inline void mtxRotateZYX(float* _result, float _ax, float _ay, float _az)
- {
- const float sx = fsin(_ax);
- const float cx = fcos(_ax);
- const float sy = fsin(_ay);
- const float cy = fcos(_ay);
- const float sz = fsin(_az);
- const float cz = fcos(_az);
-
- memset(_result, 0, sizeof(float)*16);
- _result[ 0] = cy*cz;
- _result[ 1] = cz*sx*sy-cx*sz;
- _result[ 2] = cx*cz*sy+sx*sz;
- _result[ 4] = cy*sz;
- _result[ 5] = cx*cz + sx*sy*sz;
- _result[ 6] = -cz*sx + cx*sy*sz;
- _result[ 8] = -sy;
- _result[ 9] = cy*sx;
- _result[10] = cx*cy;
- _result[15] = 1.0f;
- };
+ ///
+ void mtxOrtho(float* _result, float _left, float _right, float _bottom, float _top, float _near, float _far, float _offset = 0.0f, bool _oglNdc = false);
- inline void mtxSRT(float* _result, float _sx, float _sy, float _sz, float _ax, float _ay, float _az, float _tx, float _ty, float _tz)
- {
- const float sx = fsin(_ax);
- const float cx = fcos(_ax);
- const float sy = fsin(_ay);
- const float cy = fcos(_ay);
- const float sz = fsin(_az);
- const float cz = fcos(_az);
-
- const float sxsz = sx*sz;
- const float cycz = cy*cz;
-
- _result[ 0] = _sx * (cycz - sxsz*sy);
- _result[ 1] = _sx * -cx*sz;
- _result[ 2] = _sx * (cz*sy + cy*sxsz);
- _result[ 3] = 0.0f;
-
- _result[ 4] = _sy * (cz*sx*sy + cy*sz);
- _result[ 5] = _sy * cx*cz;
- _result[ 6] = _sy * (sy*sz -cycz*sx);
- _result[ 7] = 0.0f;
-
- _result[ 8] = _sz * -cx*sy;
- _result[ 9] = _sz * sx;
- _result[10] = _sz * cx*cy;
- _result[11] = 0.0f;
-
- _result[12] = _tx;
- _result[13] = _ty;
- _result[14] = _tz;
- _result[15] = 1.0f;
- }
-
- inline void vec3MulMtx(float* __restrict _result, const float* __restrict _vec, const float* __restrict _mat)
- {
- _result[0] = _vec[0] * _mat[ 0] + _vec[1] * _mat[4] + _vec[2] * _mat[ 8] + _mat[12];
- _result[1] = _vec[0] * _mat[ 1] + _vec[1] * _mat[5] + _vec[2] * _mat[ 9] + _mat[13];
- _result[2] = _vec[0] * _mat[ 2] + _vec[1] * _mat[6] + _vec[2] * _mat[10] + _mat[14];
- }
+ ///
+ void mtxOrthoLh(float* _result, float _left, float _right, float _bottom, float _top, float _near, float _far, float _offset = 0.0f, bool _oglNdc = false);
- inline void vec3MulMtxH(float* __restrict _result, const float* __restrict _vec, const float* __restrict _mat)
- {
- float xx = _vec[0] * _mat[ 0] + _vec[1] * _mat[4] + _vec[2] * _mat[ 8] + _mat[12];
- float yy = _vec[0] * _mat[ 1] + _vec[1] * _mat[5] + _vec[2] * _mat[ 9] + _mat[13];
- float zz = _vec[0] * _mat[ 2] + _vec[1] * _mat[6] + _vec[2] * _mat[10] + _mat[14];
- float ww = _vec[0] * _mat[ 3] + _vec[1] * _mat[7] + _vec[2] * _mat[11] + _mat[15];
- float invW = fsign(ww)/ww;
- _result[0] = xx*invW;
- _result[1] = yy*invW;
- _result[2] = zz*invW;
- }
-
- inline void vec4MulMtx(float* __restrict _result, const float* __restrict _vec, const float* __restrict _mat)
- {
- _result[0] = _vec[0] * _mat[ 0] + _vec[1] * _mat[4] + _vec[2] * _mat[ 8] + _vec[3] * _mat[12];
- _result[1] = _vec[0] * _mat[ 1] + _vec[1] * _mat[5] + _vec[2] * _mat[ 9] + _vec[3] * _mat[13];
- _result[2] = _vec[0] * _mat[ 2] + _vec[1] * _mat[6] + _vec[2] * _mat[10] + _vec[3] * _mat[14];
- _result[3] = _vec[0] * _mat[ 3] + _vec[1] * _mat[7] + _vec[2] * _mat[11] + _vec[3] * _mat[15];
- }
+ ///
+ void mtxOrthoRh(float* _result, float _left, float _right, float _bottom, float _top, float _near, float _far, float _offset = 0.0f, bool _oglNdc = false);
- inline void mtxMul(float* __restrict _result, const float* __restrict _a, const float* __restrict _b)
- {
- vec4MulMtx(&_result[ 0], &_a[ 0], _b);
- vec4MulMtx(&_result[ 4], &_a[ 4], _b);
- vec4MulMtx(&_result[ 8], &_a[ 8], _b);
- vec4MulMtx(&_result[12], &_a[12], _b);
- }
+ ///
+ void mtxRotateX(float* _result, float _ax);
- inline void mtxTranspose(float* __restrict _result, const float* __restrict _a)
- {
- _result[ 0] = _a[ 0];
- _result[ 4] = _a[ 1];
- _result[ 8] = _a[ 2];
- _result[12] = _a[ 3];
- _result[ 1] = _a[ 4];
- _result[ 5] = _a[ 5];
- _result[ 9] = _a[ 6];
- _result[13] = _a[ 7];
- _result[ 2] = _a[ 8];
- _result[ 6] = _a[ 9];
- _result[10] = _a[10];
- _result[14] = _a[11];
- _result[ 3] = _a[12];
- _result[ 7] = _a[13];
- _result[11] = _a[14];
- _result[15] = _a[15];
- }
-
- inline void mtx3Inverse(float* __restrict _result, const float* __restrict _a)
- {
- float xx = _a[0];
- float xy = _a[1];
- float xz = _a[2];
- float yx = _a[3];
- float yy = _a[4];
- float yz = _a[5];
- float zx = _a[6];
- float zy = _a[7];
- float zz = _a[8];
-
- float det = 0.0f;
- det += xx * (yy*zz - yz*zy);
- det -= xy * (yx*zz - yz*zx);
- det += xz * (yx*zy - yy*zx);
-
- float invDet = 1.0f/det;
-
- _result[0] = +(yy*zz - yz*zy) * invDet;
- _result[1] = -(xy*zz - xz*zy) * invDet;
- _result[2] = +(xy*yz - xz*yy) * invDet;
-
- _result[3] = -(yx*zz - yz*zx) * invDet;
- _result[4] = +(xx*zz - xz*zx) * invDet;
- _result[5] = -(xx*yz - xz*yx) * invDet;
-
- _result[6] = +(yx*zy - yy*zx) * invDet;
- _result[7] = -(xx*zy - xy*zx) * invDet;
- _result[8] = +(xx*yy - xy*yx) * invDet;
- }
-
- inline void mtxInverse(float* __restrict _result, const float* __restrict _a)
- {
- float xx = _a[ 0];
- float xy = _a[ 1];
- float xz = _a[ 2];
- float xw = _a[ 3];
- float yx = _a[ 4];
- float yy = _a[ 5];
- float yz = _a[ 6];
- float yw = _a[ 7];
- float zx = _a[ 8];
- float zy = _a[ 9];
- float zz = _a[10];
- float zw = _a[11];
- float wx = _a[12];
- float wy = _a[13];
- float wz = _a[14];
- float ww = _a[15];
-
- float det = 0.0f;
- det += xx * (yy*(zz*ww - zw*wz) - yz*(zy*ww - zw*wy) + yw*(zy*wz - zz*wy) );
- det -= xy * (yx*(zz*ww - zw*wz) - yz*(zx*ww - zw*wx) + yw*(zx*wz - zz*wx) );
- det += xz * (yx*(zy*ww - zw*wy) - yy*(zx*ww - zw*wx) + yw*(zx*wy - zy*wx) );
- det -= xw * (yx*(zy*wz - zz*wy) - yy*(zx*wz - zz*wx) + yz*(zx*wy - zy*wx) );
-
- float invDet = 1.0f/det;
-
- _result[ 0] = +(yy*(zz*ww - wz*zw) - yz*(zy*ww - wy*zw) + yw*(zy*wz - wy*zz) ) * invDet;
- _result[ 1] = -(xy*(zz*ww - wz*zw) - xz*(zy*ww - wy*zw) + xw*(zy*wz - wy*zz) ) * invDet;
- _result[ 2] = +(xy*(yz*ww - wz*yw) - xz*(yy*ww - wy*yw) + xw*(yy*wz - wy*yz) ) * invDet;
- _result[ 3] = -(xy*(yz*zw - zz*yw) - xz*(yy*zw - zy*yw) + xw*(yy*zz - zy*yz) ) * invDet;
-
- _result[ 4] = -(yx*(zz*ww - wz*zw) - yz*(zx*ww - wx*zw) + yw*(zx*wz - wx*zz) ) * invDet;
- _result[ 5] = +(xx*(zz*ww - wz*zw) - xz*(zx*ww - wx*zw) + xw*(zx*wz - wx*zz) ) * invDet;
- _result[ 6] = -(xx*(yz*ww - wz*yw) - xz*(yx*ww - wx*yw) + xw*(yx*wz - wx*yz) ) * invDet;
- _result[ 7] = +(xx*(yz*zw - zz*yw) - xz*(yx*zw - zx*yw) + xw*(yx*zz - zx*yz) ) * invDet;
-
- _result[ 8] = +(yx*(zy*ww - wy*zw) - yy*(zx*ww - wx*zw) + yw*(zx*wy - wx*zy) ) * invDet;
- _result[ 9] = -(xx*(zy*ww - wy*zw) - xy*(zx*ww - wx*zw) + xw*(zx*wy - wx*zy) ) * invDet;
- _result[10] = +(xx*(yy*ww - wy*yw) - xy*(yx*ww - wx*yw) + xw*(yx*wy - wx*yy) ) * invDet;
- _result[11] = -(xx*(yy*zw - zy*yw) - xy*(yx*zw - zx*yw) + xw*(yx*zy - zx*yy) ) * invDet;
-
- _result[12] = -(yx*(zy*wz - wy*zz) - yy*(zx*wz - wx*zz) + yz*(zx*wy - wx*zy) ) * invDet;
- _result[13] = +(xx*(zy*wz - wy*zz) - xy*(zx*wz - wx*zz) + xz*(zx*wy - wx*zy) ) * invDet;
- _result[14] = -(xx*(yy*wz - wy*yz) - xy*(yx*wz - wx*yz) + xz*(yx*wy - wx*yy) ) * invDet;
- _result[15] = +(xx*(yy*zz - zy*yz) - xy*(yx*zz - zx*yz) + xz*(yx*zy - zx*yy) ) * invDet;
- }
+ ///
+ void mtxRotateY(float* _result, float _ay);
- /// Convert LH to RH projection matrix and vice versa.
- inline void mtxProjFlipHandedness(float* __restrict _dst, const float* __restrict _src)
- {
- _dst[ 0] = -_src[ 0];
- _dst[ 1] = -_src[ 1];
- _dst[ 2] = -_src[ 2];
- _dst[ 3] = -_src[ 3];
- _dst[ 4] = _src[ 4];
- _dst[ 5] = _src[ 5];
- _dst[ 6] = _src[ 6];
- _dst[ 7] = _src[ 7];
- _dst[ 8] = -_src[ 8];
- _dst[ 9] = -_src[ 9];
- _dst[10] = -_src[10];
- _dst[11] = -_src[11];
- _dst[12] = _src[12];
- _dst[13] = _src[13];
- _dst[14] = _src[14];
- _dst[15] = _src[15];
- }
+ ///
+ void mtxRotateZ(float* _result, float _az);
- /// Convert LH to RH view matrix and vice versa.
- inline void mtxViewFlipHandedness(float* __restrict _dst, const float* __restrict _src)
- {
- _dst[ 0] = -_src[ 0];
- _dst[ 1] = _src[ 1];
- _dst[ 2] = -_src[ 2];
- _dst[ 3] = _src[ 3];
- _dst[ 4] = -_src[ 4];
- _dst[ 5] = _src[ 5];
- _dst[ 6] = -_src[ 6];
- _dst[ 7] = _src[ 7];
- _dst[ 8] = -_src[ 8];
- _dst[ 9] = _src[ 9];
- _dst[10] = -_src[10];
- _dst[11] = _src[11];
- _dst[12] = -_src[12];
- _dst[13] = _src[13];
- _dst[14] = -_src[14];
- _dst[15] = _src[15];
- }
-
- inline void calcNormal(float _result[3], float _va[3], float _vb[3], float _vc[3])
- {
- float ba[3];
- vec3Sub(ba, _vb, _va);
+ ///
+ void mtxRotateXY(float* _result, float _ax, float _ay);
- float ca[3];
- vec3Sub(ca, _vc, _va);
+ ///
+ void mtxRotateXYZ(float* _result, float _ax, float _ay, float _az);
- float baxca[3];
- vec3Cross(baxca, ba, ca);
+ ///
+ void mtxRotateZYX(float* _result, float _ax, float _ay, float _az);
- vec3Norm(_result, baxca);
- }
+ ///
+ void mtxSRT(float* _result, float _sx, float _sy, float _sz, float _ax, float _ay, float _az, float _tx, float _ty, float _tz);
- inline void calcPlane(float _result[4], float _va[3], float _vb[3], float _vc[3])
- {
- float normal[3];
- calcNormal(normal, _va, _vb, _vc);
+ ///
+ void vec3MulMtx(float* __restrict _result, const float* __restrict _vec, const float* __restrict _mat);
- _result[0] = normal[0];
- _result[1] = normal[1];
- _result[2] = normal[2];
- _result[3] = -vec3Dot(normal, _va);
- }
+ ///
+ void vec3MulMtxH(float* __restrict _result, const float* __restrict _vec, const float* __restrict _mat);
- inline void calcLinearFit2D(float _result[2], const void* _points, uint32_t _stride, uint32_t _numPoints)
- {
- float sumX = 0.0f;
- float sumY = 0.0f;
- float sumXX = 0.0f;
- float sumXY = 0.0f;
+ ///
+ void vec4MulMtx(float* __restrict _result, const float* __restrict _vec, const float* __restrict _mat);
- const uint8_t* ptr = (const uint8_t*)_points;
- for (uint32_t ii = 0; ii < _numPoints; ++ii, ptr += _stride)
- {
- const float* point = (const float*)ptr;
- float xx = point[0];
- float yy = point[1];
- sumX += xx;
- sumY += yy;
- sumXX += xx*xx;
- sumXY += xx*yy;
- }
-
- // [ sum(x^2) sum(x) ] [ A ] = [ sum(x*y) ]
- // [ sum(x) numPoints ] [ B ] [ sum(y) ]
-
- float det = (sumXX*_numPoints - sumX*sumX);
- float invDet = 1.0f/det;
-
- _result[0] = (-sumX * sumY + _numPoints * sumXY) * invDet;
- _result[1] = (sumXX * sumY - sumX * sumXY) * invDet;
- }
-
- inline void calcLinearFit3D(float _result[3], const void* _points, uint32_t _stride, uint32_t _numPoints)
- {
- float sumX = 0.0f;
- float sumY = 0.0f;
- float sumZ = 0.0f;
- float sumXX = 0.0f;
- float sumXY = 0.0f;
- float sumXZ = 0.0f;
- float sumYY = 0.0f;
- float sumYZ = 0.0f;
-
- const uint8_t* ptr = (const uint8_t*)_points;
- for (uint32_t ii = 0; ii < _numPoints; ++ii, ptr += _stride)
- {
- const float* point = (const float*)ptr;
- float xx = point[0];
- float yy = point[1];
- float zz = point[2];
-
- sumX += xx;
- sumY += yy;
- sumZ += zz;
- sumXX += xx*xx;
- sumXY += xx*yy;
- sumXZ += xx*zz;
- sumYY += yy*yy;
- sumYZ += yy*zz;
- }
-
- // [ sum(x^2) sum(x*y) sum(x) ] [ A ] [ sum(x*z) ]
- // [ sum(x*y) sum(y^2) sum(y) ] [ B ] = [ sum(y*z) ]
- // [ sum(x) sum(y) numPoints ] [ C ] [ sum(z) ]
-
- float mtx[9] =
- {
- sumXX, sumXY, sumX,
- sumXY, sumYY, sumY,
- sumX, sumY, float(_numPoints),
- };
- float invMtx[9];
- mtx3Inverse(invMtx, mtx);
+ ///
+ void mtxMul(float* __restrict _result, const float* __restrict _a, const float* __restrict _b);
- _result[0] = invMtx[0]*sumXZ + invMtx[1]*sumYZ + invMtx[2]*sumZ;
- _result[1] = invMtx[3]*sumXZ + invMtx[4]*sumYZ + invMtx[5]*sumZ;
- _result[2] = invMtx[6]*sumXZ + invMtx[7]*sumYZ + invMtx[8]*sumZ;
- }
+ ///
+ void mtxTranspose(float* __restrict _result, const float* __restrict _a);
- inline void rgbToHsv(float _hsv[3], const float _rgb[3])
- {
- const float rr = _rgb[0];
- const float gg = _rgb[1];
- const float bb = _rgb[2];
+ ///
+ void mtx3Inverse(float* __restrict _result, const float* __restrict _a);
- const float s0 = fstep(bb, gg);
+ ///
+ void mtxInverse(float* __restrict _result, const float* __restrict _a);
- const float px = flerp(bb, gg, s0);
- const float py = flerp(gg, bb, s0);
- const float pz = flerp(-1.0f, 0.0f, s0);
- const float pw = flerp(2.0f/3.0f, -1.0f/3.0f, s0);
+ /// Convert LH to RH projection matrix and vice versa.
+ ///
+ void mtxProjFlipHandedness(float* __restrict _dst, const float* __restrict _src);
- const float s1 = fstep(px, rr);
+ /// Convert LH to RH view matrix and vice versa.
+ ///
+ void mtxViewFlipHandedness(float* __restrict _dst, const float* __restrict _src);
- const float qx = flerp(px, rr, s1);
- const float qy = py;
- const float qz = flerp(pw, pz, s1);
- const float qw = flerp(rr, px, s1);
+ ///
+ void calcNormal(float _result[3], float _va[3], float _vb[3], float _vc[3]);
- const float dd = qx - fmin(qw, qy);
- const float ee = 1.0e-10f;
+ ///
+ void calcPlane(float _result[4], float _va[3], float _vb[3], float _vc[3]);
- _hsv[0] = fabsolute(qz + (qw - qy) / (6.0f * dd + ee) );
- _hsv[1] = dd / (qx + ee);
- _hsv[2] = qx;
- }
+ ///
+ void calcLinearFit2D(float _result[2], const void* _points, uint32_t _stride, uint32_t _numPoints);
- inline void hsvToRgb(float _rgb[3], const float _hsv[3])
- {
- const float hh = _hsv[0];
- const float ss = _hsv[1];
- const float vv = _hsv[2];
+ ///
+ void calcLinearFit3D(float _result[3], const void* _points, uint32_t _stride, uint32_t _numPoints);
- const float px = fabsolute(ffract(hh + 1.0f ) * 6.0f - 3.0f);
- const float py = fabsolute(ffract(hh + 2.0f/3.0f) * 6.0f - 3.0f);
- const float pz = fabsolute(ffract(hh + 1.0f/3.0f) * 6.0f - 3.0f);
+ ///
+ void rgbToHsv(float _hsv[3], const float _rgb[3]);
- _rgb[0] = vv * flerp(1.0f, fsaturate(px - 1.0f), ss);
- _rgb[1] = vv * flerp(1.0f, fsaturate(py - 1.0f), ss);
- _rgb[2] = vv * flerp(1.0f, fsaturate(pz - 1.0f), ss);
- }
+ ///
+ void hsvToRgb(float _rgb[3], const float _hsv[3]);
} // namespace bx
+#include "fpumath.inl"
+
#endif // BX_FPU_MATH_H_HEADER_GUARD
diff --git a/3rdparty/bx/include/bx/fpumath.inl b/3rdparty/bx/include/bx/fpumath.inl
new file mode 100644
index 00000000000..8a81fc27819
--- /dev/null
+++ b/3rdparty/bx/include/bx/fpumath.inl
@@ -0,0 +1,1416 @@
+/*
+ * Copyright 2011-2017 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ */
+
+// FPU math lib
+
+#ifndef BX_FPU_MATH_H_HEADER_GUARD
+# error "Must be included from bx/fpumath.h!"
+#endif // BX_FPU_MATH_H_HEADER_GUARD
+
+#include "bx.h"
+#include <math.h>
+#include <string.h>
+
+namespace bx
+{
+ inline float toRad(float _deg)
+ {
+ return _deg * pi / 180.0f;
+ }
+
+ inline float toDeg(float _rad)
+ {
+ return _rad * 180.0f / pi;
+ }
+
+ inline uint32_t floatToBits(float _a)
+ {
+ union { float f; uint32_t ui; } u = { _a };
+ return u.ui;
+ }
+
+ inline float bitsToFloat(uint32_t _a)
+ {
+ union { uint32_t ui; float f; } u = { _a };
+ return u.f;
+ }
+
+ inline uint64_t doubleToBits(double _a)
+ {
+ union { double f; uint64_t ui; } u = { _a };
+ return u.ui;
+ }
+
+ inline double bitsToDouble(uint64_t _a)
+ {
+ union { uint64_t ui; double f; } u = { _a };
+ return u.f;
+ }
+
+ inline bool isNan(float _f)
+ {
+ const uint32_t tmp = floatToBits(_f) & INT32_MAX;
+ return tmp > UINT32_C(0x7f800000);
+ }
+
+ inline bool isNan(double _f)
+ {
+ const uint64_t tmp = doubleToBits(_f) & INT64_MAX;
+ return tmp > UINT64_C(0x7ff0000000000000);
+ }
+
+ inline bool isFinite(float _f)
+ {
+ const uint32_t tmp = floatToBits(_f) & INT32_MAX;
+ return tmp < UINT32_C(0x7f800000);
+ }
+
+ inline bool isFinite(double _f)
+ {
+ const uint64_t tmp = doubleToBits(_f) & INT64_MAX;
+ return tmp < UINT64_C(0x7ff0000000000000);
+ }
+
+ inline bool isInfinite(float _f)
+ {
+ const uint32_t tmp = floatToBits(_f) & INT32_MAX;
+ return tmp == UINT32_C(0x7f800000);
+ }
+
+ inline bool isInfinite(double _f)
+ {
+ const uint64_t tmp = doubleToBits(_f) & INT64_MAX;
+ return tmp == UINT64_C(0x7ff0000000000000);
+ }
+
+ inline float ffloor(float _f)
+ {
+ return floorf(_f);
+ }
+
+ inline float fceil(float _f)
+ {
+ return ceilf(_f);
+ }
+
+ inline float fround(float _f)
+ {
+ return ffloor(_f + 0.5f);
+ }
+
+ inline float fmin(float _a, float _b)
+ {
+ return _a < _b ? _a : _b;
+ }
+
+ inline float fmax(float _a, float _b)
+ {
+ return _a > _b ? _a : _b;
+ }
+
+ inline float fmin3(float _a, float _b, float _c)
+ {
+ return fmin(_a, fmin(_b, _c) );
+ }
+
+ inline float fmax3(float _a, float _b, float _c)
+ {
+ return fmax(_a, fmax(_b, _c) );
+ }
+
+ inline float fclamp(float _a, float _min, float _max)
+ {
+ return fmin(fmax(_a, _min), _max);
+ }
+
+ inline float fsaturate(float _a)
+ {
+ return fclamp(_a, 0.0f, 1.0f);
+ }
+
+ inline float flerp(float _a, float _b, float _t)
+ {
+ return _a + (_b - _a) * _t;
+ }
+
+ inline float fsign(float _a)
+ {
+ return _a < 0.0f ? -1.0f : 1.0f;
+ }
+
+ inline float fabsolute(float _a)
+ {
+ return fabsf(_a);
+ }
+
+ inline float fsq(float _a)
+ {
+ return _a * _a;
+ }
+
+ inline float fsin(float _a)
+ {
+ return sinf(_a);
+ }
+
+ inline float fasin(float _a)
+ {
+ return asinf(_a);
+ }
+
+ inline float fcos(float _a)
+ {
+ return cosf(_a);
+ }
+
+ inline float facos(float _a)
+ {
+ return acosf(_a);
+ }
+
+ inline float fatan2(float _y, float _x)
+ {
+ return atan2f(_y, _x);
+ }
+
+ inline float fpow(float _a, float _b)
+ {
+ return powf(_a, _b);
+ }
+
+ inline float fexp2(float _a)
+ {
+ return fpow(2.0f, _a);
+ }
+
+ inline float flog(float _a)
+ {
+ return logf(_a);
+ }
+
+ inline float flog2(float _a)
+ {
+ return flog(_a) * 1.442695041f;
+ }
+
+ inline float fsqrt(float _a)
+ {
+ return sqrtf(_a);
+ }
+
+ inline float frsqrt(float _a)
+ {
+ return 1.0f/fsqrt(_a);
+ }
+
+ inline float ffract(float _a)
+ {
+ return _a - floorf(_a);
+ }
+
+ inline float fmod(float _a, float _b)
+ {
+ return fmodf(_a, _b);
+ }
+
+ inline bool fequal(float _a, float _b, float _epsilon)
+ {
+ // http://realtimecollisiondetection.net/blog/?p=89
+ const float lhs = fabsolute(_a - _b);
+ const float rhs = _epsilon * fmax3(1.0f, fabsolute(_a), fabsolute(_b) );
+ return lhs <= rhs;
+ }
+
+ inline bool fequal(const float* __restrict _a, const float* __restrict _b, uint32_t _num, float _epsilon)
+ {
+ bool equal = fequal(_a[0], _b[0], _epsilon);
+ for (uint32_t ii = 1; equal && ii < _num; ++ii)
+ {
+ equal = fequal(_a[ii], _b[ii], _epsilon);
+ }
+ return equal;
+ }
+
+ inline float fwrap(float _a, float _wrap)
+ {
+ const float mod = fmod(_a, _wrap);
+ const float result = mod < 0.0f ? _wrap + mod : mod;
+ return result;
+ }
+
+ inline float fstep(float _edge, float _a)
+ {
+ return _a < _edge ? 0.0f : 1.0f;
+ }
+
+ inline float fpulse(float _a, float _start, float _end)
+ {
+ return fstep(_a, _start) - fstep(_a, _end);
+ }
+
+ inline float fsmoothstep(float _a)
+ {
+ return fsq(_a)*(3.0f - 2.0f*_a);
+ }
+
+ inline float fbias(float _time, float _bias)
+ {
+ return _time / ( ( (1.0f/_bias - 2.0f)*(1.0f - _time) ) + 1.0f);
+ }
+
+ inline float fgain(float _time, float _gain)
+ {
+ if (_time < 0.5f)
+ {
+ return fbias(_time * 2.0f, _gain) * 0.5f;
+ }
+
+ return fbias(_time * 2.0f - 1.0f, 1.0f - _gain) * 0.5f + 0.5f;
+ }
+
+ inline void vec3Move(float* __restrict _result, const float* __restrict _a)
+ {
+ _result[0] = _a[0];
+ _result[1] = _a[1];
+ _result[2] = _a[2];
+ }
+
+ inline void vec3Abs(float* __restrict _result, const float* __restrict _a)
+ {
+ _result[0] = fabsolute(_a[0]);
+ _result[1] = fabsolute(_a[1]);
+ _result[2] = fabsolute(_a[2]);
+ }
+
+ inline void vec3Neg(float* __restrict _result, const float* __restrict _a)
+ {
+ _result[0] = -_a[0];
+ _result[1] = -_a[1];
+ _result[2] = -_a[2];
+ }
+
+ inline void vec3Add(float* __restrict _result, const float* __restrict _a, const float* __restrict _b)
+ {
+ _result[0] = _a[0] + _b[0];
+ _result[1] = _a[1] + _b[1];
+ _result[2] = _a[2] + _b[2];
+ }
+
+ inline void vec3Add(float* __restrict _result, const float* __restrict _a, float _b)
+ {
+ _result[0] = _a[0] + _b;
+ _result[1] = _a[1] + _b;
+ _result[2] = _a[2] + _b;
+ }
+
+ inline void vec3Sub(float* __restrict _result, const float* __restrict _a, const float* __restrict _b)
+ {
+ _result[0] = _a[0] - _b[0];
+ _result[1] = _a[1] - _b[1];
+ _result[2] = _a[2] - _b[2];
+ }
+
+ inline void vec3Sub(float* __restrict _result, const float* __restrict _a, float _b)
+ {
+ _result[0] = _a[0] - _b;
+ _result[1] = _a[1] - _b;
+ _result[2] = _a[2] - _b;
+ }
+
+ inline void vec3Mul(float* __restrict _result, const float* __restrict _a, const float* __restrict _b)
+ {
+ _result[0] = _a[0] * _b[0];
+ _result[1] = _a[1] * _b[1];
+ _result[2] = _a[2] * _b[2];
+ }
+
+ inline void vec3Mul(float* __restrict _result, const float* __restrict _a, float _b)
+ {
+ _result[0] = _a[0] * _b;
+ _result[1] = _a[1] * _b;
+ _result[2] = _a[2] * _b;
+ }
+
+ inline float vec3Dot(const float* __restrict _a, const float* __restrict _b)
+ {
+ return _a[0]*_b[0] + _a[1]*_b[1] + _a[2]*_b[2];
+ }
+
+ inline void vec3Cross(float* __restrict _result, const float* __restrict _a, const float* __restrict _b)
+ {
+ _result[0] = _a[1]*_b[2] - _a[2]*_b[1];
+ _result[1] = _a[2]*_b[0] - _a[0]*_b[2];
+ _result[2] = _a[0]*_b[1] - _a[1]*_b[0];
+ }
+
+ inline float vec3Length(const float* _a)
+ {
+ return fsqrt(vec3Dot(_a, _a) );
+ }
+
+ inline void vec3Lerp(float* __restrict _result, const float* __restrict _a, const float* __restrict _b, float _t)
+ {
+ _result[0] = flerp(_a[0], _b[0], _t);
+ _result[1] = flerp(_a[1], _b[1], _t);
+ _result[2] = flerp(_a[2], _b[2], _t);
+ }
+
+ inline void vec3Lerp(float* __restrict _result, const float* __restrict _a, const float* __restrict _b, const float* __restrict _c)
+ {
+ _result[0] = flerp(_a[0], _b[0], _c[0]);
+ _result[1] = flerp(_a[1], _b[1], _c[1]);
+ _result[2] = flerp(_a[2], _b[2], _c[2]);
+ }
+
+ inline float vec3Norm(float* __restrict _result, const float* __restrict _a)
+ {
+ const float len = vec3Length(_a);
+ const float invLen = 1.0f/len;
+ _result[0] = _a[0] * invLen;
+ _result[1] = _a[1] * invLen;
+ _result[2] = _a[2] * invLen;
+ return len;
+ }
+
+ inline void vec3Min(float* __restrict _result, const float* __restrict _a, const float* __restrict _b)
+ {
+ _result[0] = fmin(_a[0], _b[0]);
+ _result[1] = fmin(_a[1], _b[1]);
+ _result[2] = fmin(_a[2], _b[2]);
+ }
+
+ inline void vec3Max(float* __restrict _result, const float* __restrict _a, const float* __restrict _b)
+ {
+ _result[0] = fmax(_a[0], _b[0]);
+ _result[1] = fmax(_a[1], _b[1]);
+ _result[2] = fmax(_a[2], _b[2]);
+ }
+
+ inline void vec3Rcp(float* __restrict _result, const float* __restrict _a)
+ {
+ _result[0] = 1.0f / _a[0];
+ _result[1] = 1.0f / _a[1];
+ _result[2] = 1.0f / _a[2];
+ }
+
+ inline void vec3TangentFrame(const float* __restrict _n, float* __restrict _t, float* __restrict _b)
+ {
+ const float nx = _n[0];
+ const float ny = _n[1];
+ const float nz = _n[2];
+
+ if (bx::fabsolute(nx) > bx::fabsolute(nz) )
+ {
+ float invLen = 1.0f / bx::fsqrt(nx*nx + nz*nz);
+ _t[0] = -nz * invLen;
+ _t[1] = 0.0f;
+ _t[2] = nx * invLen;
+ }
+ else
+ {
+ float invLen = 1.0f / bx::fsqrt(ny*ny + nz*nz);
+ _t[0] = 0.0f;
+ _t[1] = nz * invLen;
+ _t[2] = -ny * invLen;
+ }
+
+ bx::vec3Cross(_b, _n, _t);
+ }
+
+ inline void vec3TangentFrame(const float* __restrict _n, float* __restrict _t, float* __restrict _b, float _angle)
+ {
+ vec3TangentFrame(_n, _t, _b);
+
+ const float sa = fsin(_angle);
+ const float ca = fcos(_angle);
+
+ _t[0] = -sa * _b[0] + ca * _t[0];
+ _t[1] = -sa * _b[1] + ca * _t[1];
+ _t[2] = -sa * _b[2] + ca * _t[2];
+
+ bx::vec3Cross(_b, _n, _t);
+ }
+
+ inline void quatIdentity(float* _result)
+ {
+ _result[0] = 0.0f;
+ _result[1] = 0.0f;
+ _result[2] = 0.0f;
+ _result[3] = 1.0f;
+ }
+
+ inline void quatMove(float* __restrict _result, const float* __restrict _a)
+ {
+ _result[0] = _a[0];
+ _result[1] = _a[1];
+ _result[2] = _a[2];
+ _result[3] = _a[3];
+ }
+
+ inline void quatMulXYZ(float* __restrict _result, const float* __restrict _qa, const float* __restrict _qb)
+ {
+ const float ax = _qa[0];
+ const float ay = _qa[1];
+ const float az = _qa[2];
+ const float aw = _qa[3];
+
+ const float bx = _qb[0];
+ const float by = _qb[1];
+ const float bz = _qb[2];
+ const float bw = _qb[3];
+
+ _result[0] = aw * bx + ax * bw + ay * bz - az * by;
+ _result[1] = aw * by - ax * bz + ay * bw + az * bx;
+ _result[2] = aw * bz + ax * by - ay * bx + az * bw;
+ }
+
+ inline void quatMul(float* __restrict _result, const float* __restrict _qa, const float* __restrict _qb)
+ {
+ const float ax = _qa[0];
+ const float ay = _qa[1];
+ const float az = _qa[2];
+ const float aw = _qa[3];
+
+ const float bx = _qb[0];
+ const float by = _qb[1];
+ const float bz = _qb[2];
+ const float bw = _qb[3];
+
+ _result[0] = aw * bx + ax * bw + ay * bz - az * by;
+ _result[1] = aw * by - ax * bz + ay * bw + az * bx;
+ _result[2] = aw * bz + ax * by - ay * bx + az * bw;
+ _result[3] = aw * bw - ax * bx - ay * by - az * bz;
+ }
+
+ inline void quatInvert(float* __restrict _result, const float* __restrict _quat)
+ {
+ _result[0] = -_quat[0];
+ _result[1] = -_quat[1];
+ _result[2] = -_quat[2];
+ _result[3] = _quat[3];
+ }
+
+ inline float quatDot(const float* __restrict _a, const float* __restrict _b)
+ {
+ return _a[0]*_b[0]
+ + _a[1]*_b[1]
+ + _a[2]*_b[2]
+ + _a[3]*_b[3]
+ ;
+ }
+
+ inline void quatNorm(float* __restrict _result, const float* __restrict _quat)
+ {
+ const float norm = quatDot(_quat, _quat);
+ if (0.0f < norm)
+ {
+ const float invNorm = 1.0f / fsqrt(norm);
+ _result[0] = _quat[0] * invNorm;
+ _result[1] = _quat[1] * invNorm;
+ _result[2] = _quat[2] * invNorm;
+ _result[3] = _quat[3] * invNorm;
+ }
+ else
+ {
+ quatIdentity(_result);
+ }
+ }
+
+ inline void quatToEuler(float* __restrict _result, const float* __restrict _quat)
+ {
+ const float x = _quat[0];
+ const float y = _quat[1];
+ const float z = _quat[2];
+ const float w = _quat[3];
+
+ const float yy = y * y;
+ const float zz = z * z;
+
+ const float xx = x * x;
+ _result[0] = fatan2(2.0f * (x * w - y * z), 1.0f - 2.0f * (xx + zz) );
+ _result[1] = fatan2(2.0f * (y * w + x * z), 1.0f - 2.0f * (yy + zz) );
+ _result[2] = fasin (2.0f * (x * y + z * w) );
+ }
+
+ inline void quatRotateAxis(float* __restrict _result, const float* _axis, float _angle)
+ {
+ const float ha = _angle * 0.5f;
+ const float ca = fcos(ha);
+ const float sa = fsin(ha);
+ _result[0] = _axis[0] * sa;
+ _result[1] = _axis[1] * sa;
+ _result[2] = _axis[2] * sa;
+ _result[3] = ca;
+ }
+
+ inline void quatRotateX(float* _result, float _ax)
+ {
+ const float hx = _ax * 0.5f;
+ const float cx = fcos(hx);
+ const float sx = fsin(hx);
+ _result[0] = sx;
+ _result[1] = 0.0f;
+ _result[2] = 0.0f;
+ _result[3] = cx;
+ }
+
+ inline void quatRotateY(float* _result, float _ay)
+ {
+ const float hy = _ay * 0.5f;
+ const float cy = fcos(hy);
+ const float sy = fsin(hy);
+ _result[0] = 0.0f;
+ _result[1] = sy;
+ _result[2] = 0.0f;
+ _result[3] = cy;
+ }
+
+ inline void quatRotateZ(float* _result, float _az)
+ {
+ const float hz = _az * 0.5f;
+ const float cz = fcos(hz);
+ const float sz = fsin(hz);
+ _result[0] = 0.0f;
+ _result[1] = 0.0f;
+ _result[2] = sz;
+ _result[3] = cz;
+ }
+
+ inline void vec3MulQuat(float* __restrict _result, const float* __restrict _vec, const float* __restrict _quat)
+ {
+ float tmp0[4];
+ quatInvert(tmp0, _quat);
+
+ float qv[4];
+ qv[0] = _vec[0];
+ qv[1] = _vec[1];
+ qv[2] = _vec[2];
+ qv[3] = 0.0f;
+
+ float tmp1[4];
+ quatMul(tmp1, tmp0, qv);
+
+ quatMulXYZ(_result, tmp1, _quat);
+ }
+
+ inline void mtxIdentity(float* _result)
+ {
+ memset(_result, 0, sizeof(float)*16);
+ _result[0] = _result[5] = _result[10] = _result[15] = 1.0f;
+ }
+
+ inline void mtxTranslate(float* _result, float _tx, float _ty, float _tz)
+ {
+ mtxIdentity(_result);
+ _result[12] = _tx;
+ _result[13] = _ty;
+ _result[14] = _tz;
+ }
+
+ inline void mtxScale(float* _result, float _sx, float _sy, float _sz)
+ {
+ memset(_result, 0, sizeof(float) * 16);
+ _result[0] = _sx;
+ _result[5] = _sy;
+ _result[10] = _sz;
+ _result[15] = 1.0f;
+ }
+
+ inline void mtxScale(float* _result, float _scale)
+ {
+ mtxScale(_result, _scale, _scale, _scale);
+ }
+
+ inline void mtxFromNormal(float* __restrict _result, const float* __restrict _normal, float _scale, const float* __restrict _pos)
+ {
+ float tangent[3];
+ float bitangent[3];
+ vec3TangentFrame(_normal, tangent, bitangent);
+
+ vec3Mul(&_result[ 0], bitangent, _scale);
+ vec3Mul(&_result[ 4], _normal, _scale);
+ vec3Mul(&_result[ 8], tangent, _scale);
+
+ _result[ 3] = 0.0f;
+ _result[ 7] = 0.0f;
+ _result[11] = 0.0f;
+ _result[12] = _pos[0];
+ _result[13] = _pos[1];
+ _result[14] = _pos[2];
+ _result[15] = 1.0f;
+ }
+
+ inline void mtxFromNormal(float* __restrict _result, const float* __restrict _normal, float _scale, const float* __restrict _pos, float _angle)
+ {
+ float tangent[3];
+ float bitangent[3];
+ vec3TangentFrame(_normal, tangent, bitangent, _angle);
+
+ vec3Mul(&_result[ 0], bitangent, _scale);
+ vec3Mul(&_result[ 4], _normal, _scale);
+ vec3Mul(&_result[ 8], tangent, _scale);
+
+ _result[ 3] = 0.0f;
+ _result[ 7] = 0.0f;
+ _result[11] = 0.0f;
+ _result[12] = _pos[0];
+ _result[13] = _pos[1];
+ _result[14] = _pos[2];
+ _result[15] = 1.0f;
+ }
+
+ inline void mtxQuat(float* __restrict _result, const float* __restrict _quat)
+ {
+ const float x = _quat[0];
+ const float y = _quat[1];
+ const float z = _quat[2];
+ const float w = _quat[3];
+
+ const float x2 = x + x;
+ const float y2 = y + y;
+ const float z2 = z + z;
+ const float x2x = x2 * x;
+ const float x2y = x2 * y;
+ const float x2z = x2 * z;
+ const float x2w = x2 * w;
+ const float y2y = y2 * y;
+ const float y2z = y2 * z;
+ const float y2w = y2 * w;
+ const float z2z = z2 * z;
+ const float z2w = z2 * w;
+
+ _result[ 0] = 1.0f - (y2y + z2z);
+ _result[ 1] = x2y - z2w;
+ _result[ 2] = x2z + y2w;
+ _result[ 3] = 0.0f;
+
+ _result[ 4] = x2y + z2w;
+ _result[ 5] = 1.0f - (x2x + z2z);
+ _result[ 6] = y2z - x2w;
+ _result[ 7] = 0.0f;
+
+ _result[ 8] = x2z - y2w;
+ _result[ 9] = y2z + x2w;
+ _result[10] = 1.0f - (x2x + y2y);
+ _result[11] = 0.0f;
+
+ _result[12] = 0.0f;
+ _result[13] = 0.0f;
+ _result[14] = 0.0f;
+ _result[15] = 1.0f;
+ }
+
+ inline void mtxQuatTranslation(float* __restrict _result, const float* __restrict _quat, const float* __restrict _translation)
+ {
+ mtxQuat(_result, _quat);
+ _result[12] = -(_result[0]*_translation[0] + _result[4]*_translation[1] + _result[ 8]*_translation[2]);
+ _result[13] = -(_result[1]*_translation[0] + _result[5]*_translation[1] + _result[ 9]*_translation[2]);
+ _result[14] = -(_result[2]*_translation[0] + _result[6]*_translation[1] + _result[10]*_translation[2]);
+ }
+
+ inline void mtxQuatTranslationHMD(float* __restrict _result, const float* __restrict _quat, const float* __restrict _translation)
+ {
+ float quat[4];
+ quat[0] = -_quat[0];
+ quat[1] = -_quat[1];
+ quat[2] = _quat[2];
+ quat[3] = _quat[3];
+ mtxQuatTranslation(_result, quat, _translation);
+ }
+
+ inline void mtxLookAt_Impl(float* __restrict _result, const float* __restrict _eye, const float* __restrict _view, const float* __restrict _up)
+ {
+ float up[3] = { 0.0f, 1.0f, 0.0f };
+ if (NULL != _up)
+ {
+ up[0] = _up[0];
+ up[1] = _up[1];
+ up[2] = _up[2];
+ }
+
+ float tmp[4];
+ vec3Cross(tmp, up, _view);
+
+ float right[4];
+ vec3Norm(right, tmp);
+
+ vec3Cross(up, _view, right);
+
+ memset(_result, 0, sizeof(float)*16);
+ _result[ 0] = right[0];
+ _result[ 1] = up[0];
+ _result[ 2] = _view[0];
+
+ _result[ 4] = right[1];
+ _result[ 5] = up[1];
+ _result[ 6] = _view[1];
+
+ _result[ 8] = right[2];
+ _result[ 9] = up[2];
+ _result[10] = _view[2];
+
+ _result[12] = -vec3Dot(right, _eye);
+ _result[13] = -vec3Dot(up, _eye);
+ _result[14] = -vec3Dot(_view, _eye);
+ _result[15] = 1.0f;
+ }
+
+ inline void mtxLookAtLh(float* __restrict _result, const float* __restrict _eye, const float* __restrict _at, const float* __restrict _up)
+ {
+ float tmp[4];
+ vec3Sub(tmp, _at, _eye);
+
+ float view[4];
+ vec3Norm(view, tmp);
+
+ mtxLookAt_Impl(_result, _eye, view, _up);
+ }
+
+ inline void mtxLookAtRh(float* __restrict _result, const float* __restrict _eye, const float* __restrict _at, const float* __restrict _up)
+ {
+ float tmp[4];
+ vec3Sub(tmp, _eye, _at);
+
+ float view[4];
+ vec3Norm(view, tmp);
+
+ mtxLookAt_Impl(_result, _eye, view, _up);
+ }
+
+ inline void mtxLookAt(float* __restrict _result, const float* __restrict _eye, const float* __restrict _at, const float* __restrict _up)
+ {
+ mtxLookAtLh(_result, _eye, _at, _up);
+ }
+
+ template <Handness::Enum HandnessT>
+ inline void mtxProjXYWH(float* _result, float _x, float _y, float _width, float _height, float _near, float _far, bool _oglNdc)
+ {
+ const float diff = _far-_near;
+ const float aa = _oglNdc ? (_far+_near)/diff : _far/diff;
+ const float bb = _oglNdc ? (2.0f*_far*_near)/diff : _near*aa;
+
+ memset(_result, 0, sizeof(float)*16);
+ _result[ 0] = _width;
+ _result[ 5] = _height;
+ _result[ 8] = (Handness::Right == HandnessT) ? _x : -_x;
+ _result[ 9] = (Handness::Right == HandnessT) ? _y : -_y;
+ _result[10] = (Handness::Right == HandnessT) ? -aa : aa;
+ _result[11] = (Handness::Right == HandnessT) ? -1.0f : 1.0f;
+ _result[14] = -bb;
+ }
+
+ template <Handness::Enum HandnessT>
+ inline void mtxProj_impl(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, float _far, bool _oglNdc)
+ {
+ const float invDiffRl = 1.0f/(_rt - _lt);
+ const float invDiffUd = 1.0f/(_ut - _dt);
+ const float width = 2.0f*_near * invDiffRl;
+ const float height = 2.0f*_near * invDiffUd;
+ const float xx = (_rt + _lt) * invDiffRl;
+ const float yy = (_ut + _dt) * invDiffUd;
+ mtxProjXYWH<HandnessT>(_result, xx, yy, width, height, _near, _far, _oglNdc);
+ }
+
+ template <Handness::Enum HandnessT>
+ inline void mtxProj_impl(float* _result, const float _fov[4], float _near, float _far, bool _oglNdc)
+ {
+ mtxProj_impl<HandnessT>(_result, _fov[0], _fov[1], _fov[2], _fov[3], _near, _far, _oglNdc);
+ }
+
+ template <Handness::Enum HandnessT>
+ inline void mtxProj_impl(float* _result, float _fovy, float _aspect, float _near, float _far, bool _oglNdc)
+ {
+ const float height = 1.0f/tanf(toRad(_fovy)*0.5f);
+ const float width = height * 1.0f/_aspect;
+ mtxProjXYWH<HandnessT>(_result, 0.0f, 0.0f, width, height, _near, _far, _oglNdc);
+ }
+
+ inline void mtxProj(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, float _far, bool _oglNdc)
+ {
+ mtxProj_impl<Handness::Left>(_result, _ut, _dt, _lt, _rt, _near, _far, _oglNdc);
+ }
+
+ inline void mtxProj(float* _result, const float _fov[4], float _near, float _far, bool _oglNdc)
+ {
+ mtxProj_impl<Handness::Left>(_result, _fov, _near, _far, _oglNdc);
+ }
+
+ inline void mtxProj(float* _result, float _fovy, float _aspect, float _near, float _far, bool _oglNdc)
+ {
+ mtxProj_impl<Handness::Left>(_result, _fovy, _aspect, _near, _far, _oglNdc);
+ }
+
+ inline void mtxProjLh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, float _far, bool _oglNdc)
+ {
+ mtxProj_impl<Handness::Left>(_result, _ut, _dt, _lt, _rt, _near, _far, _oglNdc);
+ }
+
+ inline void mtxProjLh(float* _result, const float _fov[4], float _near, float _far, bool _oglNdc)
+ {
+ mtxProj_impl<Handness::Left>(_result, _fov, _near, _far, _oglNdc);
+ }
+
+ inline void mtxProjLh(float* _result, float _fovy, float _aspect, float _near, float _far, bool _oglNdc)
+ {
+ mtxProj_impl<Handness::Left>(_result, _fovy, _aspect, _near, _far, _oglNdc);
+ }
+
+ inline void mtxProjRh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, float _far, bool _oglNdc)
+ {
+ mtxProj_impl<Handness::Right>(_result, _ut, _dt, _lt, _rt, _near, _far, _oglNdc);
+ }
+
+ inline void mtxProjRh(float* _result, const float _fov[4], float _near, float _far, bool _oglNdc)
+ {
+ mtxProj_impl<Handness::Right>(_result, _fov, _near, _far, _oglNdc);
+ }
+
+ inline void mtxProjRh(float* _result, float _fovy, float _aspect, float _near, float _far, bool _oglNdc)
+ {
+ mtxProj_impl<Handness::Right>(_result, _fovy, _aspect, _near, _far, _oglNdc);
+ }
+
+ template <NearFar::Enum NearFarT, Handness::Enum HandnessT>
+ inline void mtxProjInfXYWH(float* _result, float _x, float _y, float _width, float _height, float _near, bool _oglNdc)
+ {
+ float aa;
+ float bb;
+ if (BX_ENABLED(NearFar::Reverse == NearFarT) )
+ {
+ aa = _oglNdc ? -1.0f : 0.0f;
+ bb = _oglNdc ? -2.0f*_near : -_near;
+ }
+ else
+ {
+ aa = 1.0f;
+ bb = _oglNdc ? 2.0f*_near : _near;
+ }
+
+ memset(_result, 0, sizeof(float)*16);
+ _result[ 0] = _width;
+ _result[ 5] = _height;
+ _result[ 8] = (Handness::Right == HandnessT) ? _x : -_x;
+ _result[ 9] = (Handness::Right == HandnessT) ? _y : -_y;
+ _result[10] = (Handness::Right == HandnessT) ? -aa : aa;
+ _result[11] = (Handness::Right == HandnessT) ? -1.0f : 1.0f;
+ _result[14] = -bb;
+ }
+
+ template <NearFar::Enum NearFarT, Handness::Enum HandnessT>
+ inline void mtxProjInf_impl(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc)
+ {
+ const float invDiffRl = 1.0f/(_rt - _lt);
+ const float invDiffUd = 1.0f/(_ut - _dt);
+ const float width = 2.0f*_near * invDiffRl;
+ const float height = 2.0f*_near * invDiffUd;
+ const float xx = (_rt + _lt) * invDiffRl;
+ const float yy = (_ut + _dt) * invDiffUd;
+ mtxProjInfXYWH<NearFarT,HandnessT>(_result, xx, yy, width, height, _near, _oglNdc);
+ }
+
+ template <NearFar::Enum NearFarT, Handness::Enum HandnessT>
+ inline void mtxProjInf_impl(float* _result, const float _fov[4], float _near, bool _oglNdc)
+ {
+ mtxProjInf_impl<NearFarT,HandnessT>(_result, _fov[0], _fov[1], _fov[2], _fov[3], _near, _oglNdc);
+ }
+
+ template <NearFar::Enum NearFarT, Handness::Enum HandnessT>
+ inline void mtxProjInf_impl(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc)
+ {
+ const float height = 1.0f/tanf(toRad(_fovy)*0.5f);
+ const float width = height * 1.0f/_aspect;
+ mtxProjInfXYWH<NearFarT,HandnessT>(_result, 0.0f, 0.0f, width, height, _near, _oglNdc);
+ }
+
+ inline void mtxProjInf(float* _result, const float _fov[4], float _near, bool _oglNdc)
+ {
+ mtxProjInf_impl<NearFar::Default,Handness::Left>(_result, _fov, _near, _oglNdc);
+ }
+
+ inline void mtxProjInf(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc)
+ {
+ mtxProjInf_impl<NearFar::Default,Handness::Left>(_result, _ut, _dt, _lt, _rt, _near, _oglNdc);
+ }
+
+ inline void mtxProjInf(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc)
+ {
+ mtxProjInf_impl<NearFar::Default,Handness::Left>(_result, _fovy, _aspect, _near, _oglNdc);
+ }
+
+ inline void mtxProjInfLh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc)
+ {
+ mtxProjInf_impl<NearFar::Default,Handness::Left>(_result, _ut, _dt, _lt, _rt, _near, _oglNdc);
+ }
+
+ inline void mtxProjInfLh(float* _result, const float _fov[4], float _near, bool _oglNdc)
+ {
+ mtxProjInf_impl<NearFar::Default,Handness::Left>(_result, _fov, _near, _oglNdc);
+ }
+
+ inline void mtxProjInfLh(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc)
+ {
+ mtxProjInf_impl<NearFar::Default,Handness::Left>(_result, _fovy, _aspect, _near, _oglNdc);
+ }
+
+ inline void mtxProjInfRh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc)
+ {
+ mtxProjInf_impl<NearFar::Default,Handness::Right>(_result, _ut, _dt, _lt, _rt, _near, _oglNdc);
+ }
+
+ inline void mtxProjInfRh(float* _result, const float _fov[4], float _near, bool _oglNdc)
+ {
+ mtxProjInf_impl<NearFar::Default,Handness::Right>(_result, _fov, _near, _oglNdc);
+ }
+
+ inline void mtxProjInfRh(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc)
+ {
+ mtxProjInf_impl<NearFar::Default,Handness::Right>(_result, _fovy, _aspect, _near, _oglNdc);
+ }
+
+ inline void mtxProjRevInfLh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc)
+ {
+ mtxProjInf_impl<NearFar::Reverse,Handness::Left>(_result, _ut, _dt, _lt, _rt, _near, _oglNdc);
+ }
+
+ inline void mtxProjRevInfLh(float* _result, const float _fov[4], float _near, bool _oglNdc)
+ {
+ mtxProjInf_impl<NearFar::Reverse,Handness::Left>(_result, _fov, _near, _oglNdc);
+ }
+
+ inline void mtxProjRevInfLh(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc)
+ {
+ mtxProjInf_impl<NearFar::Reverse,Handness::Left>(_result, _fovy, _aspect, _near, _oglNdc);
+ }
+
+ inline void mtxProjRevInfRh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc)
+ {
+ mtxProjInf_impl<NearFar::Reverse,Handness::Right>(_result, _ut, _dt, _lt, _rt, _near, _oglNdc);
+ }
+
+ inline void mtxProjRevInfRh(float* _result, const float _fov[4], float _near, bool _oglNdc)
+ {
+ mtxProjInf_impl<NearFar::Reverse,Handness::Right>(_result, _fov, _near, _oglNdc);
+ }
+
+ inline void mtxProjRevInfRh(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc)
+ {
+ mtxProjInf_impl<NearFar::Reverse,Handness::Right>(_result, _fovy, _aspect, _near, _oglNdc);
+ }
+
+ template <Handness::Enum HandnessT>
+ inline void mtxOrtho_impl(float* _result, float _left, float _right, float _bottom, float _top, float _near, float _far, float _offset, bool _oglNdc)
+ {
+ const float aa = 2.0f/(_right - _left);
+ const float bb = 2.0f/(_top - _bottom);
+ const float cc = (_oglNdc ? 2.0f : 1.0f) / (_far - _near);
+ const float dd = (_left + _right)/(_left - _right);
+ const float ee = (_top + _bottom)/(_bottom - _top);
+ const float ff = _oglNdc ? (_near + _far)/(_near - _far) : _near/(_near - _far);
+
+ memset(_result, 0, sizeof(float)*16);
+ _result[ 0] = aa;
+ _result[ 5] = bb;
+ _result[10] = (Handness::Right == HandnessT) ? -cc : cc;
+ _result[12] = dd + _offset;
+ _result[13] = ee;
+ _result[14] = ff;
+ _result[15] = 1.0f;
+ }
+
+ inline void mtxOrtho(float* _result, float _left, float _right, float _bottom, float _top, float _near, float _far, float _offset, bool _oglNdc)
+ {
+ mtxOrtho_impl<Handness::Left>(_result, _left, _right, _bottom, _top, _near, _far, _offset, _oglNdc);
+ }
+
+ inline void mtxOrthoLh(float* _result, float _left, float _right, float _bottom, float _top, float _near, float _far, float _offset, bool _oglNdc)
+ {
+ mtxOrtho_impl<Handness::Left>(_result, _left, _right, _bottom, _top, _near, _far, _offset, _oglNdc);
+ }
+
+ inline void mtxOrthoRh(float* _result, float _left, float _right, float _bottom, float _top, float _near, float _far, float _offset, bool _oglNdc)
+ {
+ mtxOrtho_impl<Handness::Right>(_result, _left, _right, _bottom, _top, _near, _far, _offset, _oglNdc);
+ }
+
+ inline void mtxRotateX(float* _result, float _ax)
+ {
+ const float sx = fsin(_ax);
+ const float cx = fcos(_ax);
+
+ memset(_result, 0, sizeof(float)*16);
+ _result[ 0] = 1.0f;
+ _result[ 5] = cx;
+ _result[ 6] = -sx;
+ _result[ 9] = sx;
+ _result[10] = cx;
+ _result[15] = 1.0f;
+ }
+
+ inline void mtxRotateY(float* _result, float _ay)
+ {
+ const float sy = fsin(_ay);
+ const float cy = fcos(_ay);
+
+ memset(_result, 0, sizeof(float)*16);
+ _result[ 0] = cy;
+ _result[ 2] = sy;
+ _result[ 5] = 1.0f;
+ _result[ 8] = -sy;
+ _result[10] = cy;
+ _result[15] = 1.0f;
+ }
+
+ inline void mtxRotateZ(float* _result, float _az)
+ {
+ const float sz = fsin(_az);
+ const float cz = fcos(_az);
+
+ memset(_result, 0, sizeof(float)*16);
+ _result[ 0] = cz;
+ _result[ 1] = -sz;
+ _result[ 4] = sz;
+ _result[ 5] = cz;
+ _result[10] = 1.0f;
+ _result[15] = 1.0f;
+ }
+
+ inline void mtxRotateXY(float* _result, float _ax, float _ay)
+ {
+ const float sx = fsin(_ax);
+ const float cx = fcos(_ax);
+ const float sy = fsin(_ay);
+ const float cy = fcos(_ay);
+
+ memset(_result, 0, sizeof(float)*16);
+ _result[ 0] = cy;
+ _result[ 2] = sy;
+ _result[ 4] = sx*sy;
+ _result[ 5] = cx;
+ _result[ 6] = -sx*cy;
+ _result[ 8] = -cx*sy;
+ _result[ 9] = sx;
+ _result[10] = cx*cy;
+ _result[15] = 1.0f;
+ }
+
+ inline void mtxRotateXYZ(float* _result, float _ax, float _ay, float _az)
+ {
+ const float sx = fsin(_ax);
+ const float cx = fcos(_ax);
+ const float sy = fsin(_ay);
+ const float cy = fcos(_ay);
+ const float sz = fsin(_az);
+ const float cz = fcos(_az);
+
+ memset(_result, 0, sizeof(float)*16);
+ _result[ 0] = cy*cz;
+ _result[ 1] = -cy*sz;
+ _result[ 2] = sy;
+ _result[ 4] = cz*sx*sy + cx*sz;
+ _result[ 5] = cx*cz - sx*sy*sz;
+ _result[ 6] = -cy*sx;
+ _result[ 8] = -cx*cz*sy + sx*sz;
+ _result[ 9] = cz*sx + cx*sy*sz;
+ _result[10] = cx*cy;
+ _result[15] = 1.0f;
+ }
+
+ inline void mtxRotateZYX(float* _result, float _ax, float _ay, float _az)
+ {
+ const float sx = fsin(_ax);
+ const float cx = fcos(_ax);
+ const float sy = fsin(_ay);
+ const float cy = fcos(_ay);
+ const float sz = fsin(_az);
+ const float cz = fcos(_az);
+
+ memset(_result, 0, sizeof(float)*16);
+ _result[ 0] = cy*cz;
+ _result[ 1] = cz*sx*sy-cx*sz;
+ _result[ 2] = cx*cz*sy+sx*sz;
+ _result[ 4] = cy*sz;
+ _result[ 5] = cx*cz + sx*sy*sz;
+ _result[ 6] = -cz*sx + cx*sy*sz;
+ _result[ 8] = -sy;
+ _result[ 9] = cy*sx;
+ _result[10] = cx*cy;
+ _result[15] = 1.0f;
+ };
+
+ inline void mtxSRT(float* _result, float _sx, float _sy, float _sz, float _ax, float _ay, float _az, float _tx, float _ty, float _tz)
+ {
+ const float sx = fsin(_ax);
+ const float cx = fcos(_ax);
+ const float sy = fsin(_ay);
+ const float cy = fcos(_ay);
+ const float sz = fsin(_az);
+ const float cz = fcos(_az);
+
+ const float sxsz = sx*sz;
+ const float cycz = cy*cz;
+
+ _result[ 0] = _sx * (cycz - sxsz*sy);
+ _result[ 1] = _sx * -cx*sz;
+ _result[ 2] = _sx * (cz*sy + cy*sxsz);
+ _result[ 3] = 0.0f;
+
+ _result[ 4] = _sy * (cz*sx*sy + cy*sz);
+ _result[ 5] = _sy * cx*cz;
+ _result[ 6] = _sy * (sy*sz -cycz*sx);
+ _result[ 7] = 0.0f;
+
+ _result[ 8] = _sz * -cx*sy;
+ _result[ 9] = _sz * sx;
+ _result[10] = _sz * cx*cy;
+ _result[11] = 0.0f;
+
+ _result[12] = _tx;
+ _result[13] = _ty;
+ _result[14] = _tz;
+ _result[15] = 1.0f;
+ }
+
+ inline void vec3MulMtx(float* __restrict _result, const float* __restrict _vec, const float* __restrict _mat)
+ {
+ _result[0] = _vec[0] * _mat[ 0] + _vec[1] * _mat[4] + _vec[2] * _mat[ 8] + _mat[12];
+ _result[1] = _vec[0] * _mat[ 1] + _vec[1] * _mat[5] + _vec[2] * _mat[ 9] + _mat[13];
+ _result[2] = _vec[0] * _mat[ 2] + _vec[1] * _mat[6] + _vec[2] * _mat[10] + _mat[14];
+ }
+
+ inline void vec3MulMtxH(float* __restrict _result, const float* __restrict _vec, const float* __restrict _mat)
+ {
+ float xx = _vec[0] * _mat[ 0] + _vec[1] * _mat[4] + _vec[2] * _mat[ 8] + _mat[12];
+ float yy = _vec[0] * _mat[ 1] + _vec[1] * _mat[5] + _vec[2] * _mat[ 9] + _mat[13];
+ float zz = _vec[0] * _mat[ 2] + _vec[1] * _mat[6] + _vec[2] * _mat[10] + _mat[14];
+ float ww = _vec[0] * _mat[ 3] + _vec[1] * _mat[7] + _vec[2] * _mat[11] + _mat[15];
+ float invW = fsign(ww)/ww;
+ _result[0] = xx*invW;
+ _result[1] = yy*invW;
+ _result[2] = zz*invW;
+ }
+
+ inline void vec4MulMtx(float* __restrict _result, const float* __restrict _vec, const float* __restrict _mat)
+ {
+ _result[0] = _vec[0] * _mat[ 0] + _vec[1] * _mat[4] + _vec[2] * _mat[ 8] + _vec[3] * _mat[12];
+ _result[1] = _vec[0] * _mat[ 1] + _vec[1] * _mat[5] + _vec[2] * _mat[ 9] + _vec[3] * _mat[13];
+ _result[2] = _vec[0] * _mat[ 2] + _vec[1] * _mat[6] + _vec[2] * _mat[10] + _vec[3] * _mat[14];
+ _result[3] = _vec[0] * _mat[ 3] + _vec[1] * _mat[7] + _vec[2] * _mat[11] + _vec[3] * _mat[15];
+ }
+
+ inline void mtxMul(float* __restrict _result, const float* __restrict _a, const float* __restrict _b)
+ {
+ vec4MulMtx(&_result[ 0], &_a[ 0], _b);
+ vec4MulMtx(&_result[ 4], &_a[ 4], _b);
+ vec4MulMtx(&_result[ 8], &_a[ 8], _b);
+ vec4MulMtx(&_result[12], &_a[12], _b);
+ }
+
+ inline void mtxTranspose(float* __restrict _result, const float* __restrict _a)
+ {
+ _result[ 0] = _a[ 0];
+ _result[ 4] = _a[ 1];
+ _result[ 8] = _a[ 2];
+ _result[12] = _a[ 3];
+ _result[ 1] = _a[ 4];
+ _result[ 5] = _a[ 5];
+ _result[ 9] = _a[ 6];
+ _result[13] = _a[ 7];
+ _result[ 2] = _a[ 8];
+ _result[ 6] = _a[ 9];
+ _result[10] = _a[10];
+ _result[14] = _a[11];
+ _result[ 3] = _a[12];
+ _result[ 7] = _a[13];
+ _result[11] = _a[14];
+ _result[15] = _a[15];
+ }
+
+ /// Convert LH to RH projection matrix and vice versa.
+ inline void mtxProjFlipHandedness(float* __restrict _dst, const float* __restrict _src)
+ {
+ _dst[ 0] = -_src[ 0];
+ _dst[ 1] = -_src[ 1];
+ _dst[ 2] = -_src[ 2];
+ _dst[ 3] = -_src[ 3];
+ _dst[ 4] = _src[ 4];
+ _dst[ 5] = _src[ 5];
+ _dst[ 6] = _src[ 6];
+ _dst[ 7] = _src[ 7];
+ _dst[ 8] = -_src[ 8];
+ _dst[ 9] = -_src[ 9];
+ _dst[10] = -_src[10];
+ _dst[11] = -_src[11];
+ _dst[12] = _src[12];
+ _dst[13] = _src[13];
+ _dst[14] = _src[14];
+ _dst[15] = _src[15];
+ }
+
+ /// Convert LH to RH view matrix and vice versa.
+ inline void mtxViewFlipHandedness(float* __restrict _dst, const float* __restrict _src)
+ {
+ _dst[ 0] = -_src[ 0];
+ _dst[ 1] = _src[ 1];
+ _dst[ 2] = -_src[ 2];
+ _dst[ 3] = _src[ 3];
+ _dst[ 4] = -_src[ 4];
+ _dst[ 5] = _src[ 5];
+ _dst[ 6] = -_src[ 6];
+ _dst[ 7] = _src[ 7];
+ _dst[ 8] = -_src[ 8];
+ _dst[ 9] = _src[ 9];
+ _dst[10] = -_src[10];
+ _dst[11] = _src[11];
+ _dst[12] = -_src[12];
+ _dst[13] = _src[13];
+ _dst[14] = -_src[14];
+ _dst[15] = _src[15];
+ }
+
+ inline void calcNormal(float _result[3], float _va[3], float _vb[3], float _vc[3])
+ {
+ float ba[3];
+ vec3Sub(ba, _vb, _va);
+
+ float ca[3];
+ vec3Sub(ca, _vc, _va);
+
+ float baxca[3];
+ vec3Cross(baxca, ba, ca);
+
+ vec3Norm(_result, baxca);
+ }
+
+ inline void calcPlane(float _result[4], float _va[3], float _vb[3], float _vc[3])
+ {
+ float normal[3];
+ calcNormal(normal, _va, _vb, _vc);
+
+ _result[0] = normal[0];
+ _result[1] = normal[1];
+ _result[2] = normal[2];
+ _result[3] = -vec3Dot(normal, _va);
+ }
+
+ inline void calcLinearFit2D(float _result[2], const void* _points, uint32_t _stride, uint32_t _numPoints)
+ {
+ float sumX = 0.0f;
+ float sumY = 0.0f;
+ float sumXX = 0.0f;
+ float sumXY = 0.0f;
+
+ const uint8_t* ptr = (const uint8_t*)_points;
+ for (uint32_t ii = 0; ii < _numPoints; ++ii, ptr += _stride)
+ {
+ const float* point = (const float*)ptr;
+ float xx = point[0];
+ float yy = point[1];
+ sumX += xx;
+ sumY += yy;
+ sumXX += xx*xx;
+ sumXY += xx*yy;
+ }
+
+ // [ sum(x^2) sum(x) ] [ A ] = [ sum(x*y) ]
+ // [ sum(x) numPoints ] [ B ] [ sum(y) ]
+
+ float det = (sumXX*_numPoints - sumX*sumX);
+ float invDet = 1.0f/det;
+
+ _result[0] = (-sumX * sumY + _numPoints * sumXY) * invDet;
+ _result[1] = (sumXX * sumY - sumX * sumXY) * invDet;
+ }
+
+ inline void calcLinearFit3D(float _result[3], const void* _points, uint32_t _stride, uint32_t _numPoints)
+ {
+ float sumX = 0.0f;
+ float sumY = 0.0f;
+ float sumZ = 0.0f;
+ float sumXX = 0.0f;
+ float sumXY = 0.0f;
+ float sumXZ = 0.0f;
+ float sumYY = 0.0f;
+ float sumYZ = 0.0f;
+
+ const uint8_t* ptr = (const uint8_t*)_points;
+ for (uint32_t ii = 0; ii < _numPoints; ++ii, ptr += _stride)
+ {
+ const float* point = (const float*)ptr;
+ float xx = point[0];
+ float yy = point[1];
+ float zz = point[2];
+
+ sumX += xx;
+ sumY += yy;
+ sumZ += zz;
+ sumXX += xx*xx;
+ sumXY += xx*yy;
+ sumXZ += xx*zz;
+ sumYY += yy*yy;
+ sumYZ += yy*zz;
+ }
+
+ // [ sum(x^2) sum(x*y) sum(x) ] [ A ] [ sum(x*z) ]
+ // [ sum(x*y) sum(y^2) sum(y) ] [ B ] = [ sum(y*z) ]
+ // [ sum(x) sum(y) numPoints ] [ C ] [ sum(z) ]
+
+ float mtx[9] =
+ {
+ sumXX, sumXY, sumX,
+ sumXY, sumYY, sumY,
+ sumX, sumY, float(_numPoints),
+ };
+ float invMtx[9];
+ mtx3Inverse(invMtx, mtx);
+
+ _result[0] = invMtx[0]*sumXZ + invMtx[1]*sumYZ + invMtx[2]*sumZ;
+ _result[1] = invMtx[3]*sumXZ + invMtx[4]*sumYZ + invMtx[5]*sumZ;
+ _result[2] = invMtx[6]*sumXZ + invMtx[7]*sumYZ + invMtx[8]*sumZ;
+ }
+
+ inline void rgbToHsv(float _hsv[3], const float _rgb[3])
+ {
+ const float rr = _rgb[0];
+ const float gg = _rgb[1];
+ const float bb = _rgb[2];
+
+ const float s0 = fstep(bb, gg);
+
+ const float px = flerp(bb, gg, s0);
+ const float py = flerp(gg, bb, s0);
+ const float pz = flerp(-1.0f, 0.0f, s0);
+ const float pw = flerp(2.0f/3.0f, -1.0f/3.0f, s0);
+
+ const float s1 = fstep(px, rr);
+
+ const float qx = flerp(px, rr, s1);
+ const float qy = py;
+ const float qz = flerp(pw, pz, s1);
+ const float qw = flerp(rr, px, s1);
+
+ const float dd = qx - fmin(qw, qy);
+ const float ee = 1.0e-10f;
+
+ _hsv[0] = fabsolute(qz + (qw - qy) / (6.0f * dd + ee) );
+ _hsv[1] = dd / (qx + ee);
+ _hsv[2] = qx;
+ }
+
+ inline void hsvToRgb(float _rgb[3], const float _hsv[3])
+ {
+ const float hh = _hsv[0];
+ const float ss = _hsv[1];
+ const float vv = _hsv[2];
+
+ const float px = fabsolute(ffract(hh + 1.0f ) * 6.0f - 3.0f);
+ const float py = fabsolute(ffract(hh + 2.0f/3.0f) * 6.0f - 3.0f);
+ const float pz = fabsolute(ffract(hh + 1.0f/3.0f) * 6.0f - 3.0f);
+
+ _rgb[0] = vv * flerp(1.0f, fsaturate(px - 1.0f), ss);
+ _rgb[1] = vv * flerp(1.0f, fsaturate(py - 1.0f), ss);
+ _rgb[2] = vv * flerp(1.0f, fsaturate(pz - 1.0f), ss);
+ }
+
+} // namespace bx
diff --git a/3rdparty/bx/include/bx/handlealloc.h b/3rdparty/bx/include/bx/handlealloc.h
index 04303f4f49c..cf8efc585c5 100644
--- a/3rdparty/bx/include/bx/handlealloc.h
+++ b/3rdparty/bx/include/bx/handlealloc.h
@@ -18,130 +18,65 @@ namespace bx
public:
static const uint16_t invalid = UINT16_MAX;
- HandleAlloc(uint16_t _maxHandles)
- : m_numHandles(0)
- , m_maxHandles(_maxHandles)
- {
- reset();
- }
+ ///
+ HandleAlloc(uint16_t _maxHandles);
- ~HandleAlloc()
- {
- }
+ ///
+ ~HandleAlloc();
- const uint16_t* getHandles() const
- {
- return getDensePtr();
- }
+ ///
+ const uint16_t* getHandles() const;
- uint16_t getHandleAt(uint16_t _at) const
- {
- return getDensePtr()[_at];
- }
+ ///
+ uint16_t getHandleAt(uint16_t _at) const;
- uint16_t getNumHandles() const
- {
- return m_numHandles;
- }
+ ///
+ uint16_t getNumHandles() const;
- uint16_t getMaxHandles() const
- {
- return m_maxHandles;
- }
+ ///
+ uint16_t getMaxHandles() const;
- uint16_t alloc()
- {
- if (m_numHandles < m_maxHandles)
- {
- uint16_t index = m_numHandles;
- ++m_numHandles;
-
- uint16_t* dense = getDensePtr();
- uint16_t handle = dense[index];
- uint16_t* sparse = getSparsePtr();
- sparse[handle] = index;
- return handle;
- }
-
- return invalid;
- }
-
- bool isValid(uint16_t _handle) const
- {
- uint16_t* dense = getDensePtr();
- uint16_t* sparse = getSparsePtr();
- uint16_t index = sparse[_handle];
+ ///
+ uint16_t alloc();
- return index < m_numHandles
- && dense[index] == _handle
- ;
- }
+ ///
+ bool isValid(uint16_t _handle) const;
- void free(uint16_t _handle)
- {
- uint16_t* dense = getDensePtr();
- uint16_t* sparse = getSparsePtr();
- uint16_t index = sparse[_handle];
- --m_numHandles;
- uint16_t temp = dense[m_numHandles];
- dense[m_numHandles] = _handle;
- sparse[temp] = index;
- dense[index] = temp;
- }
-
- void reset()
- {
- m_numHandles = 0;
- uint16_t* dense = getDensePtr();
- for (uint16_t ii = 0, num = m_maxHandles; ii < num; ++ii)
- {
- dense[ii] = ii;
- }
- }
+ ///
+ void free(uint16_t _handle);
+
+ ///
+ void reset();
private:
HandleAlloc();
- uint16_t* getDensePtr() const
- {
- uint8_t* ptr = (uint8_t*)reinterpret_cast<const uint8_t*>(this);
- return (uint16_t*)&ptr[sizeof(HandleAlloc)];
- }
+ ///
+ uint16_t* getDensePtr() const;
- uint16_t* getSparsePtr() const
- {
- return &getDensePtr()[m_maxHandles];
- }
+ ///
+ uint16_t* getSparsePtr() const;
uint16_t m_numHandles;
uint16_t m_maxHandles;
};
- inline HandleAlloc* createHandleAlloc(AllocatorI* _allocator, uint16_t _maxHandles)
- {
- uint8_t* ptr = (uint8_t*)BX_ALLOC(_allocator, sizeof(HandleAlloc) + 2*_maxHandles*sizeof(uint16_t) );
- return ::new (ptr) HandleAlloc(_maxHandles);
- }
+ ///
+ HandleAlloc* createHandleAlloc(AllocatorI* _allocator, uint16_t _maxHandles);
- inline void destroyHandleAlloc(AllocatorI* _allocator, HandleAlloc* _handleAlloc)
- {
- _handleAlloc->~HandleAlloc();
- BX_FREE(_allocator, _handleAlloc);
- }
+ ///
+ void destroyHandleAlloc(AllocatorI* _allocator, HandleAlloc* _handleAlloc);
///
template <uint16_t MaxHandlesT>
class HandleAllocT : public HandleAlloc
{
public:
- HandleAllocT()
- : HandleAlloc(MaxHandlesT)
- {
- }
+ ///
+ HandleAllocT();
- ~HandleAllocT()
- {
- }
+ ///
+ ~HandleAllocT();
private:
uint16_t m_padding[2*MaxHandlesT];
@@ -154,170 +89,51 @@ namespace bx
public:
static const uint16_t invalid = UINT16_MAX;
- HandleListT()
- {
- reset();
- }
+ ///
+ HandleListT();
- void pushBack(uint16_t _handle)
- {
- insertAfter(m_back, _handle);
- }
+ ///
+ void pushBack(uint16_t _handle);
- uint16_t popBack()
- {
- uint16_t last = invalid != m_back
- ? m_back
- : m_front
- ;
+ ///
+ uint16_t popBack();
- if (invalid != last)
- {
- remove(last);
- }
+ ///
+ void pushFront(uint16_t _handle);
- return last;
- }
+ ///
+ uint16_t popFront();
- void pushFront(uint16_t _handle)
- {
- insertBefore(m_front, _handle);
- }
-
- uint16_t popFront()
- {
- uint16_t front = m_front;
+ ///
+ uint16_t getFront() const;
- if (invalid != front)
- {
- remove(front);
- }
+ ///
+ uint16_t getBack() const;
- return front;
- }
+ ///
+ uint16_t getNext(uint16_t _handle) const;
- uint16_t getFront() const
- {
- return m_front;
- }
+ ///
+ uint16_t getPrev(uint16_t _handle) const;
- uint16_t getBack() const
- {
- return m_back;
- }
+ ///
+ void remove(uint16_t _handle);
- uint16_t getNext(uint16_t _handle) const
- {
- BX_CHECK(isValid(_handle), "Invalid handle %d!", _handle);
- const Link& curr = m_links[_handle];
- return curr.m_next;
- }
-
- uint16_t getPrev(uint16_t _handle) const
- {
- BX_CHECK(isValid(_handle), "Invalid handle %d!", _handle);
- const Link& curr = m_links[_handle];
- return curr.m_prev;
- }
-
- void remove(uint16_t _handle)
- {
- BX_CHECK(isValid(_handle), "Invalid handle %d!", _handle);
- Link& curr = m_links[_handle];
-
- if (invalid != curr.m_prev)
- {
- Link& prev = m_links[curr.m_prev];
- prev.m_next = curr.m_next;
- }
- else
- {
- m_front = curr.m_next;
- }
-
- if (invalid != curr.m_next)
- {
- Link& next = m_links[curr.m_next];
- next.m_prev = curr.m_prev;
- }
- else
- {
- m_back = curr.m_prev;
- }
-
- curr.m_prev = invalid;
- curr.m_next = invalid;
- }
-
- void reset()
- {
- memset(m_links, 0xff, sizeof(m_links) );
- m_front = invalid;
- m_back = invalid;
- }
+ ///
+ void reset();
private:
- void insertBefore(uint16_t _before, uint16_t _handle)
- {
- Link& curr = m_links[_handle];
- curr.m_next = _before;
-
- if (invalid != _before)
- {
- Link& link = m_links[_before];
- if (invalid != link.m_prev)
- {
- Link& prev = m_links[link.m_prev];
- prev.m_next = _handle;
- }
-
- curr.m_prev = link.m_prev;
- link.m_prev = _handle;
- }
-
- updateFrontBack(_handle);
- }
-
- void insertAfter(uint16_t _after, uint16_t _handle)
- {
- Link& curr = m_links[_handle];
- curr.m_prev = _after;
-
- if (invalid != _after)
- {
- Link& link = m_links[_after];
- if (invalid != link.m_next)
- {
- Link& next = m_links[link.m_next];
- next.m_prev = _handle;
- }
-
- curr.m_next = link.m_next;
- link.m_next = _handle;
- }
-
- updateFrontBack(_handle);
- }
-
- bool isValid(uint16_t _handle) const
- {
- return _handle < MaxHandlesT;
- }
+ ///
+ void insertBefore(uint16_t _before, uint16_t _handle);
- void updateFrontBack(uint16_t _handle)
- {
- Link& curr = m_links[_handle];
+ ///
+ void insertAfter(uint16_t _after, uint16_t _handle);
- if (invalid == curr.m_prev)
- {
- m_front = _handle;
- }
+ ///
+ bool isValid(uint16_t _handle) const;
- if (invalid == curr.m_next)
- {
- m_back = _handle;
- }
- }
+ ///
+ void updateFrontBack(uint16_t _handle);
uint16_t m_front;
uint16_t m_back;
@@ -338,89 +154,50 @@ namespace bx
public:
static const uint16_t invalid = UINT16_MAX;
- HandleAllocLruT()
- {
- reset();
- }
+ ///
+ HandleAllocLruT();
- ~HandleAllocLruT()
- {
- }
+ ///
+ ~HandleAllocLruT();
- const uint16_t* getHandles() const
- {
- return m_alloc.getHandles();
- }
+ ///
+ const uint16_t* getHandles() const;
- uint16_t getHandleAt(uint16_t _at) const
- {
- return m_alloc.getHandleAt(_at);
- }
+ ///
+ uint16_t getHandleAt(uint16_t _at) const;
- uint16_t getNumHandles() const
- {
- return m_alloc.getNumHandles();
- }
+ ///
+ uint16_t getNumHandles() const;
- uint16_t getMaxHandles() const
- {
- return m_alloc.getMaxHandles();
- }
+ ///
+ uint16_t getMaxHandles() const;
- uint16_t alloc()
- {
- uint16_t handle = m_alloc.alloc();
- if (invalid != handle)
- {
- m_list.pushFront(handle);
- }
- return handle;
- }
-
- bool isValid(uint16_t _handle) const
- {
- return m_alloc.isValid(_handle);
- }
+ ///
+ uint16_t alloc();
- void free(uint16_t _handle)
- {
- BX_CHECK(isValid(_handle), "Invalid handle %d!", _handle);
- m_list.remove(_handle);
- m_alloc.free(_handle);
- }
+ ///
+ bool isValid(uint16_t _handle) const;
- void touch(uint16_t _handle)
- {
- BX_CHECK(isValid(_handle), "Invalid handle %d!", _handle);
- m_list.remove(_handle);
- m_list.pushFront(_handle);
- }
+ ///
+ void free(uint16_t _handle);
- uint16_t getFront() const
- {
- return m_list.getFront();
- }
+ ///
+ void touch(uint16_t _handle);
- uint16_t getBack() const
- {
- return m_list.getBack();
- }
+ ///
+ uint16_t getFront() const;
- uint16_t getNext(uint16_t _handle) const
- {
- return m_list.getNext(_handle);
- }
+ ///
+ uint16_t getBack() const;
- uint16_t getPrev(uint16_t _handle) const
- {
- return m_list.getPrev(_handle);
- }
+ ///
+ uint16_t getNext(uint16_t _handle) const;
- void reset()
- {
- m_list.reset();
- m_alloc.reset();
- }
+ ///
+ uint16_t getPrev(uint16_t _handle) const;
+
+ ///
+ void reset();
private:
HandleListT<MaxHandlesT> m_list;
@@ -434,103 +211,34 @@ namespace bx
public:
static const uint16_t invalid = UINT16_MAX;
- HandleHashMapT()
- : m_maxCapacity(MaxCapacityT)
- {
- reset();
- }
+ ///
+ HandleHashMapT();
- ~HandleHashMapT()
- {
- }
+ ///
+ ~HandleHashMapT();
- bool insert(KeyT _key, uint16_t _handle)
- {
- if (invalid == _handle)
- {
- return false;
- }
-
- const KeyT hash = mix(_key);
- const uint32_t firstIdx = hash % MaxCapacityT;
- uint32_t idx = firstIdx;
- do
- {
- if (m_handle[idx] == invalid)
- {
- m_key[idx] = _key;
- m_handle[idx] = _handle;
- ++m_numElements;
- return true;
- }
-
- if (m_key[idx] == _key)
- {
- return false;
- }
-
- idx = (idx + 1) % MaxCapacityT;
-
- } while (idx != firstIdx);
-
- return false;
- }
-
- bool removeByKey(KeyT _key)
- {
- uint32_t idx = findIndex(_key);
- if (UINT32_MAX != idx)
- {
- removeIndex(idx);
- return true;
- }
+ ///
+ bool insert(KeyT _key, uint16_t _handle);
- return false;
- }
+ ///
+ bool removeByKey(KeyT _key);
- bool removeByHandle(uint16_t _handle)
- {
- if (invalid != _handle)
- {
- for (uint32_t idx = 0; idx < MaxCapacityT; ++idx)
- {
- if (m_handle[idx] == _handle)
- {
- removeIndex(idx);
- }
- }
- }
-
- return false;
- }
-
- uint16_t find(KeyT _key) const
- {
- uint32_t idx = findIndex(_key);
- if (UINT32_MAX != idx)
- {
- return m_handle[idx];
- }
+ ///
+ bool removeByHandle(uint16_t _handle);
- return invalid;
- }
+ ///
+ uint16_t find(KeyT _key) const;
- void reset()
- {
- memset(m_handle, 0xff, sizeof(m_handle) );
- m_numElements = 0;
- }
+ ///
+ void reset();
- uint32_t getNumElements() const
- {
- return m_numElements;
- }
+ ///
+ uint32_t getNumElements() const;
- uint32_t getMaxCapacity() const
- {
- return m_maxCapacity;
- }
+ ///
+ uint32_t getMaxCapacity() const;
+ ///
struct Iterator
{
uint16_t handle;
@@ -541,104 +249,24 @@ namespace bx
uint32_t num;
};
- Iterator first() const
- {
- Iterator it;
- it.handle = invalid;
- it.pos = 0;
- it.num = m_numElements;
-
- if (0 == it.num)
- {
- return it;
- }
-
- ++it.num;
- next(it);
- return it;
- }
-
- bool next(Iterator& _it) const
- {
- if (0 == _it.num)
- {
- return false;
- }
-
- for (
- ;_it.pos < MaxCapacityT && invalid == m_handle[_it.pos]
- ; ++_it.pos
- );
- _it.handle = m_handle[_it.pos];
- ++_it.pos;
- --_it.num;
- return true;
- }
+ ///
+ Iterator first() const;
- private:
- uint32_t findIndex(KeyT _key) const
- {
- const KeyT hash = mix(_key);
-
- const uint32_t firstIdx = hash % MaxCapacityT;
- uint32_t idx = firstIdx;
- do
- {
- if (m_handle[idx] == invalid)
- {
- return UINT32_MAX;
- }
-
- if (m_key[idx] == _key)
- {
- return idx;
- }
+ ///
+ bool next(Iterator& _it) const;
- idx = (idx + 1) % MaxCapacityT;
+ private:
+ ///
+ uint32_t findIndex(KeyT _key) const;
- } while (idx != firstIdx);
+ ///
+ void removeIndex(uint32_t _idx);
- return UINT32_MAX;
- }
+ ///
+ uint32_t mix(uint32_t _x) const;
- void removeIndex(uint32_t _idx)
- {
- m_handle[_idx] = invalid;
- --m_numElements;
-
- for (uint32_t idx = (_idx + 1) % MaxCapacityT
- ; m_handle[idx] != invalid
- ; idx = (idx + 1) % MaxCapacityT)
- {
- if (m_handle[idx] != invalid)
- {
- const KeyT key = m_key[idx];
- if (idx != findIndex(key) )
- {
- const uint16_t handle = m_handle[idx];
- m_handle[idx] = invalid;
- --m_numElements;
- insert(key, handle);
- }
- }
- }
- }
-
- uint32_t mix(uint32_t _x) const
- {
- const uint32_t tmp0 = uint32_mul(_x, UINT32_C(2246822519) );
- const uint32_t tmp1 = uint32_rol(tmp0, 13);
- const uint32_t result = uint32_mul(tmp1, UINT32_C(2654435761) );
- return result;
- }
-
- uint64_t mix(uint64_t _x) const
- {
- const uint64_t tmp0 = uint64_mul(_x, UINT64_C(14029467366897019727) );
- const uint64_t tmp1 = uint64_rol(tmp0, 31);
- const uint64_t result = uint64_mul(tmp1, UINT64_C(11400714785074694791) );
- return result;
- }
+ ///
+ uint64_t mix(uint64_t _x) const;
uint32_t m_maxCapacity;
uint32_t m_numElements;
@@ -654,86 +282,41 @@ namespace bx
public:
static const uint16_t invalid = UINT16_MAX;
- HandleHashMapAllocT()
- {
- reset();
- }
+ ///
+ HandleHashMapAllocT();
- ~HandleHashMapAllocT()
- {
- }
+ ///
+ ~HandleHashMapAllocT();
- uint16_t alloc(KeyT _key)
- {
- uint16_t handle = m_alloc.alloc();
- if (invalid == handle)
- {
- return invalid;
- }
-
- bool ok = m_table.insert(_key, handle);
- if (!ok)
- {
- m_alloc.free(handle);
- return invalid;
- }
-
- return handle;
- }
-
- void free(KeyT _key)
- {
- uint16_t handle = m_table.find(_key);
- if (invalid == handle)
- {
- return;
- }
+ ///
+ uint16_t alloc(KeyT _key);
- m_table.removeByKey(_key);
- m_alloc.free(handle);
- }
+ ///
+ void free(KeyT _key);
- void free(uint16_t _handle)
- {
- m_table.removeByHandle(_handle);
- m_alloc.free(_handle);
- }
+ ///
+ void free(uint16_t _handle);
- uint16_t find(KeyT _key) const
- {
- return m_table.find(_key);
- }
+ ///
+ uint16_t find(KeyT _key) const;
- const uint16_t* getHandles() const
- {
- return m_alloc.getHandles();
- }
+ ///
+ const uint16_t* getHandles() const;
- uint16_t getHandleAt(uint16_t _at) const
- {
- return m_alloc.getHandleAt(_at);
- }
+ ///
+ uint16_t getHandleAt(uint16_t _at) const;
- uint16_t getNumHandles() const
- {
- return m_alloc.getNumHandles();
- }
+ ///
+ uint16_t getNumHandles() const;
- uint16_t getMaxHandles() const
- {
- return m_alloc.getMaxHandles();
- }
+ ///
+ uint16_t getMaxHandles() const;
- bool isValid(uint16_t _handle) const
- {
- return m_alloc.isValid(_handle);
- }
+ ///
+ bool isValid(uint16_t _handle) const;
- void reset()
- {
- m_table.reset();
- m_alloc.reset();
- }
+ ///
+ void reset();
private:
HandleHashMapT<MaxHandlesT+MaxHandlesT/2, KeyT> m_table;
@@ -742,4 +325,6 @@ namespace bx
} // namespace bx
+#include "handlealloc.inl"
+
#endif // BX_HANDLE_ALLOC_H_HEADER_GUARD
diff --git a/3rdparty/bx/include/bx/handlealloc.inl b/3rdparty/bx/include/bx/handlealloc.inl
new file mode 100644
index 00000000000..04369b57d78
--- /dev/null
+++ b/3rdparty/bx/include/bx/handlealloc.inl
@@ -0,0 +1,712 @@
+/*
+ * Copyright 2010-2017 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ */
+
+#ifndef BX_HANDLE_ALLOC_H_HEADER_GUARD
+# error "Must be included from bx/handlealloc.h!"
+#endif // BX_HANDLE_ALLOC_H_HEADER_GUARD
+
+#include "bx.h"
+#include "allocator.h"
+#include "uint32_t.h"
+
+namespace bx
+{
+ inline HandleAlloc::HandleAlloc(uint16_t _maxHandles)
+ : m_numHandles(0)
+ , m_maxHandles(_maxHandles)
+ {
+ reset();
+ }
+
+ inline HandleAlloc::~HandleAlloc()
+ {
+ }
+
+ inline const uint16_t* HandleAlloc::getHandles() const
+ {
+ return getDensePtr();
+ }
+
+ inline uint16_t HandleAlloc::getHandleAt(uint16_t _at) const
+ {
+ return getDensePtr()[_at];
+ }
+
+ inline uint16_t HandleAlloc::getNumHandles() const
+ {
+ return m_numHandles;
+ }
+
+ inline uint16_t HandleAlloc::getMaxHandles() const
+ {
+ return m_maxHandles;
+ }
+
+ inline uint16_t HandleAlloc::alloc()
+ {
+ if (m_numHandles < m_maxHandles)
+ {
+ uint16_t index = m_numHandles;
+ ++m_numHandles;
+
+ uint16_t* dense = getDensePtr();
+ uint16_t handle = dense[index];
+ uint16_t* sparse = getSparsePtr();
+ sparse[handle] = index;
+ return handle;
+ }
+
+ return invalid;
+ }
+
+ inline bool HandleAlloc::isValid(uint16_t _handle) const
+ {
+ uint16_t* dense = getDensePtr();
+ uint16_t* sparse = getSparsePtr();
+ uint16_t index = sparse[_handle];
+
+ return index < m_numHandles
+ && dense[index] == _handle
+ ;
+ }
+
+ inline void HandleAlloc::free(uint16_t _handle)
+ {
+ uint16_t* dense = getDensePtr();
+ uint16_t* sparse = getSparsePtr();
+ uint16_t index = sparse[_handle];
+ --m_numHandles;
+ uint16_t temp = dense[m_numHandles];
+ dense[m_numHandles] = _handle;
+ sparse[temp] = index;
+ dense[index] = temp;
+ }
+
+ inline void HandleAlloc::reset()
+ {
+ m_numHandles = 0;
+ uint16_t* dense = getDensePtr();
+ for (uint16_t ii = 0, num = m_maxHandles; ii < num; ++ii)
+ {
+ dense[ii] = ii;
+ }
+ }
+
+ inline uint16_t* HandleAlloc::getDensePtr() const
+ {
+ uint8_t* ptr = (uint8_t*)reinterpret_cast<const uint8_t*>(this);
+ return (uint16_t*)&ptr[sizeof(HandleAlloc)];
+ }
+
+ inline uint16_t* HandleAlloc::getSparsePtr() const
+ {
+ return &getDensePtr()[m_maxHandles];
+ }
+
+ inline HandleAlloc* createHandleAlloc(AllocatorI* _allocator, uint16_t _maxHandles)
+ {
+ uint8_t* ptr = (uint8_t*)BX_ALLOC(_allocator, sizeof(HandleAlloc) + 2*_maxHandles*sizeof(uint16_t) );
+ return ::new (ptr) HandleAlloc(_maxHandles);
+ }
+
+ inline void destroyHandleAlloc(AllocatorI* _allocator, HandleAlloc* _handleAlloc)
+ {
+ _handleAlloc->~HandleAlloc();
+ BX_FREE(_allocator, _handleAlloc);
+ }
+
+ template <uint16_t MaxHandlesT>
+ inline HandleAllocT<MaxHandlesT>::HandleAllocT()
+ : HandleAlloc(MaxHandlesT)
+ {
+ }
+
+ template <uint16_t MaxHandlesT>
+ inline HandleAllocT<MaxHandlesT>::~HandleAllocT()
+ {
+ }
+
+ template <uint16_t MaxHandlesT>
+ inline HandleListT<MaxHandlesT>::HandleListT()
+ {
+ reset();
+ }
+
+ template <uint16_t MaxHandlesT>
+ inline void HandleListT<MaxHandlesT>::pushBack(uint16_t _handle)
+ {
+ insertAfter(m_back, _handle);
+ }
+
+ template <uint16_t MaxHandlesT>
+ inline uint16_t HandleListT<MaxHandlesT>::popBack()
+ {
+ uint16_t last = invalid != m_back
+ ? m_back
+ : m_front
+ ;
+
+ if (invalid != last)
+ {
+ remove(last);
+ }
+
+ return last;
+ }
+
+ template <uint16_t MaxHandlesT>
+ inline void HandleListT<MaxHandlesT>::pushFront(uint16_t _handle)
+ {
+ insertBefore(m_front, _handle);
+ }
+
+ template <uint16_t MaxHandlesT>
+ inline uint16_t HandleListT<MaxHandlesT>::popFront()
+ {
+ uint16_t front = m_front;
+
+ if (invalid != front)
+ {
+ remove(front);
+ }
+
+ return front;
+ }
+
+ template <uint16_t MaxHandlesT>
+ inline uint16_t HandleListT<MaxHandlesT>::getFront() const
+ {
+ return m_front;
+ }
+
+ template <uint16_t MaxHandlesT>
+ inline uint16_t HandleListT<MaxHandlesT>::getBack() const
+ {
+ return m_back;
+ }
+
+ template <uint16_t MaxHandlesT>
+ inline uint16_t HandleListT<MaxHandlesT>::getNext(uint16_t _handle) const
+ {
+ BX_CHECK(isValid(_handle), "Invalid handle %d!", _handle);
+ const Link& curr = m_links[_handle];
+ return curr.m_next;
+ }
+
+ template <uint16_t MaxHandlesT>
+ inline uint16_t HandleListT<MaxHandlesT>::getPrev(uint16_t _handle) const
+ {
+ BX_CHECK(isValid(_handle), "Invalid handle %d!", _handle);
+ const Link& curr = m_links[_handle];
+ return curr.m_prev;
+ }
+
+ template <uint16_t MaxHandlesT>
+ inline void HandleListT<MaxHandlesT>::remove(uint16_t _handle)
+ {
+ BX_CHECK(isValid(_handle), "Invalid handle %d!", _handle);
+ Link& curr = m_links[_handle];
+
+ if (invalid != curr.m_prev)
+ {
+ Link& prev = m_links[curr.m_prev];
+ prev.m_next = curr.m_next;
+ }
+ else
+ {
+ m_front = curr.m_next;
+ }
+
+ if (invalid != curr.m_next)
+ {
+ Link& next = m_links[curr.m_next];
+ next.m_prev = curr.m_prev;
+ }
+ else
+ {
+ m_back = curr.m_prev;
+ }
+
+ curr.m_prev = invalid;
+ curr.m_next = invalid;
+ }
+
+ template <uint16_t MaxHandlesT>
+ inline void HandleListT<MaxHandlesT>::reset()
+ {
+ memset(m_links, 0xff, sizeof(m_links) );
+ m_front = invalid;
+ m_back = invalid;
+ }
+
+ template <uint16_t MaxHandlesT>
+ inline void HandleListT<MaxHandlesT>::insertBefore(uint16_t _before, uint16_t _handle)
+ {
+ Link& curr = m_links[_handle];
+ curr.m_next = _before;
+
+ if (invalid != _before)
+ {
+ Link& link = m_links[_before];
+ if (invalid != link.m_prev)
+ {
+ Link& prev = m_links[link.m_prev];
+ prev.m_next = _handle;
+ }
+
+ curr.m_prev = link.m_prev;
+ link.m_prev = _handle;
+ }
+
+ updateFrontBack(_handle);
+ }
+
+ template <uint16_t MaxHandlesT>
+ inline void HandleListT<MaxHandlesT>::insertAfter(uint16_t _after, uint16_t _handle)
+ {
+ Link& curr = m_links[_handle];
+ curr.m_prev = _after;
+
+ if (invalid != _after)
+ {
+ Link& link = m_links[_after];
+ if (invalid != link.m_next)
+ {
+ Link& next = m_links[link.m_next];
+ next.m_prev = _handle;
+ }
+
+ curr.m_next = link.m_next;
+ link.m_next = _handle;
+ }
+
+ updateFrontBack(_handle);
+ }
+
+ template <uint16_t MaxHandlesT>
+ inline bool HandleListT<MaxHandlesT>::isValid(uint16_t _handle) const
+ {
+ return _handle < MaxHandlesT;
+ }
+
+ template <uint16_t MaxHandlesT>
+ inline void HandleListT<MaxHandlesT>::updateFrontBack(uint16_t _handle)
+ {
+ Link& curr = m_links[_handle];
+
+ if (invalid == curr.m_prev)
+ {
+ m_front = _handle;
+ }
+
+ if (invalid == curr.m_next)
+ {
+ m_back = _handle;
+ }
+ }
+
+ template <uint16_t MaxHandlesT>
+ inline HandleAllocLruT<MaxHandlesT>::HandleAllocLruT()
+ {
+ reset();
+ }
+
+ template <uint16_t MaxHandlesT>
+ inline HandleAllocLruT<MaxHandlesT>::~HandleAllocLruT()
+ {
+ }
+
+ template <uint16_t MaxHandlesT>
+ inline const uint16_t* HandleAllocLruT<MaxHandlesT>::getHandles() const
+ {
+ return m_alloc.getHandles();
+ }
+
+ template <uint16_t MaxHandlesT>
+ inline uint16_t HandleAllocLruT<MaxHandlesT>::getHandleAt(uint16_t _at) const
+ {
+ return m_alloc.getHandleAt(_at);
+ }
+
+ template <uint16_t MaxHandlesT>
+ inline uint16_t HandleAllocLruT<MaxHandlesT>::getNumHandles() const
+ {
+ return m_alloc.getNumHandles();
+ }
+
+ template <uint16_t MaxHandlesT>
+ inline uint16_t HandleAllocLruT<MaxHandlesT>::getMaxHandles() const
+ {
+ return m_alloc.getMaxHandles();
+ }
+
+ template <uint16_t MaxHandlesT>
+ inline uint16_t HandleAllocLruT<MaxHandlesT>::alloc()
+ {
+ uint16_t handle = m_alloc.alloc();
+ if (invalid != handle)
+ {
+ m_list.pushFront(handle);
+ }
+ return handle;
+ }
+
+ template <uint16_t MaxHandlesT>
+ inline bool HandleAllocLruT<MaxHandlesT>::isValid(uint16_t _handle) const
+ {
+ return m_alloc.isValid(_handle);
+ }
+
+ template <uint16_t MaxHandlesT>
+ inline void HandleAllocLruT<MaxHandlesT>::free(uint16_t _handle)
+ {
+ BX_CHECK(isValid(_handle), "Invalid handle %d!", _handle);
+ m_list.remove(_handle);
+ m_alloc.free(_handle);
+ }
+
+ template <uint16_t MaxHandlesT>
+ inline void HandleAllocLruT<MaxHandlesT>::touch(uint16_t _handle)
+ {
+ BX_CHECK(isValid(_handle), "Invalid handle %d!", _handle);
+ m_list.remove(_handle);
+ m_list.pushFront(_handle);
+ }
+
+ template <uint16_t MaxHandlesT>
+ inline uint16_t HandleAllocLruT<MaxHandlesT>::getFront() const
+ {
+ return m_list.getFront();
+ }
+
+ template <uint16_t MaxHandlesT>
+ inline uint16_t HandleAllocLruT<MaxHandlesT>::getBack() const
+ {
+ return m_list.getBack();
+ }
+
+ template <uint16_t MaxHandlesT>
+ inline uint16_t HandleAllocLruT<MaxHandlesT>::getNext(uint16_t _handle) const
+ {
+ return m_list.getNext(_handle);
+ }
+
+ template <uint16_t MaxHandlesT>
+ inline uint16_t HandleAllocLruT<MaxHandlesT>::getPrev(uint16_t _handle) const
+ {
+ return m_list.getPrev(_handle);
+ }
+
+ template <uint16_t MaxHandlesT>
+ inline void HandleAllocLruT<MaxHandlesT>::reset()
+ {
+ m_list.reset();
+ m_alloc.reset();
+ }
+
+ template <uint32_t MaxCapacityT, typename KeyT>
+ inline HandleHashMapT<MaxCapacityT, KeyT>::HandleHashMapT()
+ : m_maxCapacity(MaxCapacityT)
+ {
+ reset();
+ }
+
+ template <uint32_t MaxCapacityT, typename KeyT>
+ inline HandleHashMapT<MaxCapacityT, KeyT>::~HandleHashMapT()
+ {
+ }
+
+ template <uint32_t MaxCapacityT, typename KeyT>
+ inline bool HandleHashMapT<MaxCapacityT, KeyT>::insert(KeyT _key, uint16_t _handle)
+ {
+ if (invalid == _handle)
+ {
+ return false;
+ }
+
+ const KeyT hash = mix(_key);
+ const uint32_t firstIdx = hash % MaxCapacityT;
+ uint32_t idx = firstIdx;
+ do
+ {
+ if (m_handle[idx] == invalid)
+ {
+ m_key[idx] = _key;
+ m_handle[idx] = _handle;
+ ++m_numElements;
+ return true;
+ }
+
+ if (m_key[idx] == _key)
+ {
+ return false;
+ }
+
+ idx = (idx + 1) % MaxCapacityT;
+
+ } while (idx != firstIdx);
+
+ return false;
+ }
+
+ template <uint32_t MaxCapacityT, typename KeyT>
+ inline bool HandleHashMapT<MaxCapacityT, KeyT>::removeByKey(KeyT _key)
+ {
+ uint32_t idx = findIndex(_key);
+ if (UINT32_MAX != idx)
+ {
+ removeIndex(idx);
+ return true;
+ }
+
+ return false;
+ }
+
+ template <uint32_t MaxCapacityT, typename KeyT>
+ inline bool HandleHashMapT<MaxCapacityT, KeyT>::removeByHandle(uint16_t _handle)
+ {
+ if (invalid != _handle)
+ {
+ for (uint32_t idx = 0; idx < MaxCapacityT; ++idx)
+ {
+ if (m_handle[idx] == _handle)
+ {
+ removeIndex(idx);
+ }
+ }
+ }
+
+ return false;
+ }
+
+ template <uint32_t MaxCapacityT, typename KeyT>
+ inline uint16_t HandleHashMapT<MaxCapacityT, KeyT>::find(KeyT _key) const
+ {
+ uint32_t idx = findIndex(_key);
+ if (UINT32_MAX != idx)
+ {
+ return m_handle[idx];
+ }
+
+ return invalid;
+ }
+
+ template <uint32_t MaxCapacityT, typename KeyT>
+ inline void HandleHashMapT<MaxCapacityT, KeyT>::reset()
+ {
+ memset(m_handle, 0xff, sizeof(m_handle) );
+ m_numElements = 0;
+ }
+
+ template <uint32_t MaxCapacityT, typename KeyT>
+ inline uint32_t HandleHashMapT<MaxCapacityT, KeyT>::getNumElements() const
+ {
+ return m_numElements;
+ }
+
+ template <uint32_t MaxCapacityT, typename KeyT>
+ inline uint32_t HandleHashMapT<MaxCapacityT, KeyT>::getMaxCapacity() const
+ {
+ return m_maxCapacity;
+ }
+
+ template <uint32_t MaxCapacityT, typename KeyT>
+ inline typename HandleHashMapT<MaxCapacityT, KeyT>::Iterator HandleHashMapT<MaxCapacityT, KeyT>::first() const
+ {
+ Iterator it;
+ it.handle = invalid;
+ it.pos = 0;
+ it.num = m_numElements;
+
+ if (0 == it.num)
+ {
+ return it;
+ }
+
+ ++it.num;
+ next(it);
+ return it;
+ }
+
+ template <uint32_t MaxCapacityT, typename KeyT>
+ inline bool HandleHashMapT<MaxCapacityT, KeyT>::next(Iterator& _it) const
+ {
+ if (0 == _it.num)
+ {
+ return false;
+ }
+
+ for (
+ ;_it.pos < MaxCapacityT && invalid == m_handle[_it.pos]
+ ; ++_it.pos
+ );
+ _it.handle = m_handle[_it.pos];
+ ++_it.pos;
+ --_it.num;
+ return true;
+ }
+
+ template <uint32_t MaxCapacityT, typename KeyT>
+ inline uint32_t HandleHashMapT<MaxCapacityT, KeyT>::findIndex(KeyT _key) const
+ {
+ const KeyT hash = mix(_key);
+
+ const uint32_t firstIdx = hash % MaxCapacityT;
+ uint32_t idx = firstIdx;
+ do
+ {
+ if (m_handle[idx] == invalid)
+ {
+ return UINT32_MAX;
+ }
+
+ if (m_key[idx] == _key)
+ {
+ return idx;
+ }
+
+ idx = (idx + 1) % MaxCapacityT;
+
+ } while (idx != firstIdx);
+
+ return UINT32_MAX;
+ }
+
+ template <uint32_t MaxCapacityT, typename KeyT>
+ inline void HandleHashMapT<MaxCapacityT, KeyT>::removeIndex(uint32_t _idx)
+ {
+ m_handle[_idx] = invalid;
+ --m_numElements;
+
+ for (uint32_t idx = (_idx + 1) % MaxCapacityT
+ ; m_handle[idx] != invalid
+ ; idx = (idx + 1) % MaxCapacityT)
+ {
+ if (m_handle[idx] != invalid)
+ {
+ const KeyT key = m_key[idx];
+ if (idx != findIndex(key) )
+ {
+ const uint16_t handle = m_handle[idx];
+ m_handle[idx] = invalid;
+ --m_numElements;
+ insert(key, handle);
+ }
+ }
+ }
+ }
+
+ template <uint32_t MaxCapacityT, typename KeyT>
+ inline uint32_t HandleHashMapT<MaxCapacityT, KeyT>::mix(uint32_t _x) const
+ {
+ const uint32_t tmp0 = uint32_mul(_x, UINT32_C(2246822519) );
+ const uint32_t tmp1 = uint32_rol(tmp0, 13);
+ const uint32_t result = uint32_mul(tmp1, UINT32_C(2654435761) );
+ return result;
+ }
+
+ template <uint32_t MaxCapacityT, typename KeyT>
+ inline uint64_t HandleHashMapT<MaxCapacityT, KeyT>::mix(uint64_t _x) const
+ {
+ const uint64_t tmp0 = uint64_mul(_x, UINT64_C(14029467366897019727) );
+ const uint64_t tmp1 = uint64_rol(tmp0, 31);
+ const uint64_t result = uint64_mul(tmp1, UINT64_C(11400714785074694791) );
+ return result;
+ }
+
+ template <uint16_t MaxHandlesT, typename KeyT>
+ inline HandleHashMapAllocT<MaxHandlesT, KeyT>::HandleHashMapAllocT()
+ {
+ reset();
+ }
+
+ template <uint16_t MaxHandlesT, typename KeyT>
+ inline HandleHashMapAllocT<MaxHandlesT, KeyT>::~HandleHashMapAllocT()
+ {
+ }
+
+ template <uint16_t MaxHandlesT, typename KeyT>
+ inline uint16_t HandleHashMapAllocT<MaxHandlesT, KeyT>::alloc(KeyT _key)
+ {
+ uint16_t handle = m_alloc.alloc();
+ if (invalid == handle)
+ {
+ return invalid;
+ }
+
+ bool ok = m_table.insert(_key, handle);
+ if (!ok)
+ {
+ m_alloc.free(handle);
+ return invalid;
+ }
+
+ return handle;
+ }
+
+ template <uint16_t MaxHandlesT, typename KeyT>
+ inline void HandleHashMapAllocT<MaxHandlesT, KeyT>::free(KeyT _key)
+ {
+ uint16_t handle = m_table.find(_key);
+ if (invalid == handle)
+ {
+ return;
+ }
+
+ m_table.removeByKey(_key);
+ m_alloc.free(handle);
+ }
+
+ template <uint16_t MaxHandlesT, typename KeyT>
+ inline void HandleHashMapAllocT<MaxHandlesT, KeyT>::free(uint16_t _handle)
+ {
+ m_table.removeByHandle(_handle);
+ m_alloc.free(_handle);
+ }
+
+ template <uint16_t MaxHandlesT, typename KeyT>
+ inline uint16_t HandleHashMapAllocT<MaxHandlesT, KeyT>::find(KeyT _key) const
+ {
+ return m_table.find(_key);
+ }
+
+ template <uint16_t MaxHandlesT, typename KeyT>
+ inline const uint16_t* HandleHashMapAllocT<MaxHandlesT, KeyT>::getHandles() const
+ {
+ return m_alloc.getHandles();
+ }
+
+ template <uint16_t MaxHandlesT, typename KeyT>
+ inline uint16_t HandleHashMapAllocT<MaxHandlesT, KeyT>::getHandleAt(uint16_t _at) const
+ {
+ return m_alloc.getHandleAt(_at);
+ }
+
+ template <uint16_t MaxHandlesT, typename KeyT>
+ inline uint16_t HandleHashMapAllocT<MaxHandlesT, KeyT>::getNumHandles() const
+ {
+ return m_alloc.getNumHandles();
+ }
+
+ template <uint16_t MaxHandlesT, typename KeyT>
+ inline uint16_t HandleHashMapAllocT<MaxHandlesT, KeyT>::getMaxHandles() const
+ {
+ return m_alloc.getMaxHandles();
+ }
+
+ template <uint16_t MaxHandlesT, typename KeyT>
+ inline bool HandleHashMapAllocT<MaxHandlesT, KeyT>::isValid(uint16_t _handle) const
+ {
+ return m_alloc.isValid(_handle);
+ }
+
+ template <uint16_t MaxHandlesT, typename KeyT>
+ inline void HandleHashMapAllocT<MaxHandlesT, KeyT>::reset()
+ {
+ m_table.reset();
+ m_alloc.reset();
+ }
+
+} // namespace bx
diff --git a/3rdparty/bx/include/bx/hash.h b/3rdparty/bx/include/bx/hash.h
index d037c30a3c1..ec0b8164bd0 100644
--- a/3rdparty/bx/include/bx/hash.h
+++ b/3rdparty/bx/include/bx/hash.h
@@ -6,139 +6,41 @@
#ifndef BX_HASH_H_HEADER_GUARD
#define BX_HASH_H_HEADER_GUARD
-#include "bx.h"
+#include "allocator.h" // isAligned
namespace bx
{
-// MurmurHash2 was written by Austin Appleby, and is placed in the public
-// domain. The author hereby disclaims copyright to this source code.
-
-#define MURMUR_M 0x5bd1e995
-#define MURMUR_R 24
-#define mmix(_h, _k) { _k *= MURMUR_M; _k ^= _k >> MURMUR_R; _k *= MURMUR_M; _h *= MURMUR_M; _h ^= _k; }
-
+ /// MurmurHash2 was written by Austin Appleby, and is placed in the public
+ /// domain. The author hereby disclaims copyright to this source code.
+ ///
class HashMurmur2A
{
public:
- void begin(uint32_t _seed = 0)
- {
- m_hash = _seed;
- m_tail = 0;
- m_count = 0;
- m_size = 0;
- }
-
- void add(const void* _data, int _len)
- {
- if (BX_UNLIKELY(!isPtrAligned(_data, 4) ) )
- {
- addUnaligned(_data, _len);
- return;
- }
-
- addAligned(_data, _len);
- }
-
- void addAligned(const void* _data, int _len)
- {
- const uint8_t* data = (const uint8_t*)_data;
- m_size += _len;
-
- mixTail(data, _len);
-
- while(_len >= 4)
- {
- uint32_t kk = *(uint32_t*)data;
-
- mmix(m_hash, kk);
-
- data += 4;
- _len -= 4;
- }
-
- mixTail(data, _len);
- }
+ ///
+ void begin(uint32_t _seed = 0);
- void addUnaligned(const void* _data, int _len)
- {
- const uint8_t* data = (const uint8_t*)_data;
- m_size += _len;
+ ///
+ void add(const void* _data, int _len);
- mixTail(data, _len);
+ ///
+ void addAligned(const void* _data, int _len);
- while(_len >= 4)
- {
- uint32_t kk;
- readUnaligned(data, kk);
-
- mmix(m_hash, kk);
-
- data += 4;
- _len -= 4;
- }
-
- mixTail(data, _len);
- }
+ ///
+ void addUnaligned(const void* _data, int _len);
+ ///
template<typename Ty>
- void add(Ty _value)
- {
- add(&_value, sizeof(Ty) );
- }
-
- uint32_t end()
- {
- mmix(m_hash, m_tail);
- mmix(m_hash, m_size);
-
- m_hash ^= m_hash >> 13;
- m_hash *= MURMUR_M;
- m_hash ^= m_hash >> 15;
+ void add(Ty _value);
- return m_hash;
- }
+ ///
+ uint32_t end();
private:
- static void readUnaligned(const void* _data, uint32_t& _out)
- {
- const uint8_t* data = (const uint8_t*)_data;
- if (BX_ENABLED(BX_CPU_ENDIAN_BIG) )
- {
- _out = 0
- | data[0]<<24
- | data[1]<<16
- | data[2]<<8
- | data[3]
- ;
- }
- else
- {
- _out = 0
- | data[0]
- | data[1]<<8
- | data[2]<<16
- | data[3]<<24
- ;
- }
- }
-
- void mixTail(const uint8_t*& _data, int& _len)
- {
- while( _len && ((_len<4) || m_count) )
- {
- m_tail |= (*_data++) << (m_count * 8);
-
- m_count++;
- _len--;
-
- if(m_count == 4)
- {
- mmix(m_hash, m_tail);
- m_tail = 0;
- m_count = 0;
- }
- }
- }
+ ///
+ static void readUnaligned(const void* _data, uint32_t& _out);
+
+ ///
+ void mixTail(const uint8_t*& _data, int& _len);
uint32_t m_hash;
uint32_t m_tail;
@@ -146,25 +48,15 @@ namespace bx
uint32_t m_size;
};
-#undef MURMUR_M
-#undef MURMUR_R
-#undef mmix
-
- inline uint32_t hashMurmur2A(const void* _data, uint32_t _size)
- {
- HashMurmur2A murmur;
- murmur.begin();
- murmur.add(_data, (int)_size);
- return murmur.end();
- }
+ ///
+ uint32_t hashMurmur2A(const void* _data, uint32_t _size);
+ ///
template <typename Ty>
- inline uint32_t hashMurmur2A(const Ty& _data)
- {
- BX_STATIC_ASSERT(BX_TYPE_IS_POD(Ty) );
- return hashMurmur2A(&_data, sizeof(Ty) );
- }
+ uint32_t hashMurmur2A(const Ty& _data);
} // namespace bx
+#include "hash.inl"
+
#endif // BX_HASH_H_HEADER_GUARD
diff --git a/3rdparty/bx/include/bx/hash.inl b/3rdparty/bx/include/bx/hash.inl
new file mode 100644
index 00000000000..cfa3eca252c
--- /dev/null
+++ b/3rdparty/bx/include/bx/hash.inl
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2010-2017 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ */
+
+#ifndef BX_HASH_H_HEADER_GUARD
+# error "Must be included from bx/hash.h!"
+#endif // BX_HASH_H_HEADER_GUARD
+
+namespace bx
+{
+#define MURMUR_M 0x5bd1e995
+#define MURMUR_R 24
+#define mmix(_h, _k) { _k *= MURMUR_M; _k ^= _k >> MURMUR_R; _k *= MURMUR_M; _h *= MURMUR_M; _h ^= _k; }
+
+ inline void HashMurmur2A::begin(uint32_t _seed)
+ {
+ m_hash = _seed;
+ m_tail = 0;
+ m_count = 0;
+ m_size = 0;
+ }
+
+ inline void HashMurmur2A::add(const void* _data, int _len)
+ {
+ if (BX_UNLIKELY(!isAligned(_data, 4) ) )
+ {
+ addUnaligned(_data, _len);
+ return;
+ }
+
+ addAligned(_data, _len);
+ }
+
+ inline void HashMurmur2A::addAligned(const void* _data, int _len)
+ {
+ const uint8_t* data = (const uint8_t*)_data;
+ m_size += _len;
+
+ mixTail(data, _len);
+
+ while(_len >= 4)
+ {
+ uint32_t kk = *(uint32_t*)data;
+
+ mmix(m_hash, kk);
+
+ data += 4;
+ _len -= 4;
+ }
+
+ mixTail(data, _len);
+ }
+
+ inline void HashMurmur2A::addUnaligned(const void* _data, int _len)
+ {
+ const uint8_t* data = (const uint8_t*)_data;
+ m_size += _len;
+
+ mixTail(data, _len);
+
+ while(_len >= 4)
+ {
+ uint32_t kk;
+ readUnaligned(data, kk);
+
+ mmix(m_hash, kk);
+
+ data += 4;
+ _len -= 4;
+ }
+
+ mixTail(data, _len);
+ }
+
+ template<typename Ty>
+ inline void HashMurmur2A::add(Ty _value)
+ {
+ add(&_value, sizeof(Ty) );
+ }
+
+ inline uint32_t HashMurmur2A::end()
+ {
+ mmix(m_hash, m_tail);
+ mmix(m_hash, m_size);
+
+ m_hash ^= m_hash >> 13;
+ m_hash *= MURMUR_M;
+ m_hash ^= m_hash >> 15;
+
+ return m_hash;
+ }
+
+ inline void HashMurmur2A::readUnaligned(const void* _data, uint32_t& _out)
+ {
+ const uint8_t* data = (const uint8_t*)_data;
+ if (BX_ENABLED(BX_CPU_ENDIAN_BIG) )
+ {
+ _out = 0
+ | data[0]<<24
+ | data[1]<<16
+ | data[2]<<8
+ | data[3]
+ ;
+ }
+ else
+ {
+ _out = 0
+ | data[0]
+ | data[1]<<8
+ | data[2]<<16
+ | data[3]<<24
+ ;
+ }
+ }
+
+ inline void HashMurmur2A::mixTail(const uint8_t*& _data, int& _len)
+ {
+ while( _len && ((_len<4) || m_count) )
+ {
+ m_tail |= (*_data++) << (m_count * 8);
+
+ m_count++;
+ _len--;
+
+ if(m_count == 4)
+ {
+ mmix(m_hash, m_tail);
+ m_tail = 0;
+ m_count = 0;
+ }
+ }
+ }
+
+#undef MURMUR_M
+#undef MURMUR_R
+#undef mmix
+
+ inline uint32_t hashMurmur2A(const void* _data, uint32_t _size)
+ {
+ HashMurmur2A murmur;
+ murmur.begin();
+ murmur.add(_data, (int)_size);
+ return murmur.end();
+ }
+
+ template <typename Ty>
+ inline uint32_t hashMurmur2A(const Ty& _data)
+ {
+ BX_STATIC_ASSERT(BX_TYPE_IS_POD(Ty) );
+ return hashMurmur2A(&_data, sizeof(Ty) );
+ }
+
+} // namespace bx
diff --git a/3rdparty/bx/include/bx/mutex.h b/3rdparty/bx/include/bx/mutex.h
index 76a02e1a7e8..777e577b950 100644
--- a/3rdparty/bx/include/bx/mutex.h
+++ b/3rdparty/bx/include/bx/mutex.h
@@ -13,52 +13,18 @@
#if BX_CONFIG_SUPPORTS_THREADING
-#if BX_PLATFORM_NACL || BX_PLATFORM_LINUX || BX_PLATFORM_ANDROID || BX_PLATFORM_OSX
+#if 0 \
+ || BX_PLATFORM_ANDROID \
+ || BX_PLATFORM_LINUX \
+ || BX_PLATFORM_NACL \
+ || BX_PLATFORM_IOS \
+ || BX_PLATFORM_OSX
# include <pthread.h>
-#elif BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 || BX_PLATFORM_WINRT
-# include <errno.h>
-#endif // BX_PLATFORM_
+#endif //
namespace bx
{
-#if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 || BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT
- typedef CRITICAL_SECTION pthread_mutex_t;
- typedef unsigned pthread_mutexattr_t;
-
- inline int pthread_mutex_lock(pthread_mutex_t* _mutex)
- {
- EnterCriticalSection(_mutex);
- return 0;
- }
-
- inline int pthread_mutex_unlock(pthread_mutex_t* _mutex)
- {
- LeaveCriticalSection(_mutex);
- return 0;
- }
-
- inline int pthread_mutex_trylock(pthread_mutex_t* _mutex)
- {
- return TryEnterCriticalSection(_mutex) ? 0 : EBUSY;
- }
-
- inline int pthread_mutex_init(pthread_mutex_t* _mutex, pthread_mutexattr_t* /*_attr*/)
- {
-#if BX_PLATFORM_WINRT
- InitializeCriticalSectionEx(_mutex, 4000, 0); // docs recommend 4000 spincount as sane default
-#else
- InitializeCriticalSection(_mutex);
-#endif
- return 0;
- }
-
- inline int pthread_mutex_destroy(pthread_mutex_t* _mutex)
- {
- DeleteCriticalSection(_mutex);
- return 0;
- }
-#endif // BX_PLATFORM_
-
+ ///
class Mutex
{
BX_CLASS(Mutex
@@ -67,36 +33,27 @@ namespace bx
);
public:
- Mutex()
- {
- pthread_mutexattr_t attr;
-#if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 || BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT
-#else
- pthread_mutexattr_init(&attr);
- pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
-#endif // BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 || BX_PLATFORM_WINRT
- pthread_mutex_init(&m_handle, &attr);
- }
-
- ~Mutex()
- {
- pthread_mutex_destroy(&m_handle);
- }
-
- void lock()
- {
- pthread_mutex_lock(&m_handle);
- }
-
- void unlock()
- {
- pthread_mutex_unlock(&m_handle);
- }
+ ///
+ Mutex();
+
+ ///
+ ~Mutex();
+
+ ///
+ void lock();
+
+ ///
+ void unlock();
private:
+#if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 || BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT
+ CRITICAL_SECTION m_handle;
+#else
pthread_mutex_t m_handle;
+#endif // BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 || BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT
};
+ ///
class MutexScope
{
BX_CLASS(MutexScope
@@ -106,16 +63,11 @@ namespace bx
);
public:
- MutexScope(Mutex& _mutex)
- : m_mutex(_mutex)
- {
- m_mutex.lock();
- }
+ ///
+ MutexScope(Mutex& _mutex);
- ~MutexScope()
- {
- m_mutex.unlock();
- }
+ ///
+ ~MutexScope();
private:
Mutex& m_mutex;
@@ -123,6 +75,7 @@ namespace bx
typedef Mutex LwMutex;
+ ///
class LwMutexScope
{
BX_CLASS(LwMutexScope
@@ -132,16 +85,11 @@ namespace bx
);
public:
- LwMutexScope(LwMutex& _mutex)
- : m_mutex(_mutex)
- {
- m_mutex.lock();
- }
+ ///
+ LwMutexScope(LwMutex& _mutex);
- ~LwMutexScope()
- {
- m_mutex.unlock();
- }
+ ///
+ ~LwMutexScope();
private:
LwMutex& m_mutex;
@@ -149,6 +97,8 @@ namespace bx
} // namespace bx
+#include "mutex.inl"
+
#endif // BX_CONFIG_SUPPORTS_THREADING
#endif // BX_MUTEX_H_HEADER_GUARD
diff --git a/3rdparty/bx/include/bx/mutex.inl b/3rdparty/bx/include/bx/mutex.inl
new file mode 100644
index 00000000000..0d4140208e1
--- /dev/null
+++ b/3rdparty/bx/include/bx/mutex.inl
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2010-2017 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ */
+
+#ifndef BX_MUTEX_H_HEADER_GUARD
+# error "Must be included from bx/mutex.h!"
+#endif // BX_MUTEX_H_HEADER_GUARD
+
+namespace bx
+{
+ inline MutexScope::MutexScope(Mutex& _mutex)
+ : m_mutex(_mutex)
+ {
+ m_mutex.lock();
+ }
+
+ inline MutexScope::~MutexScope()
+ {
+ m_mutex.unlock();
+ }
+
+ inline LwMutexScope::LwMutexScope(LwMutex& _mutex)
+ : m_mutex(_mutex)
+ {
+ m_mutex.lock();
+ }
+
+ inline LwMutexScope::~LwMutexScope()
+ {
+ m_mutex.unlock();
+ }
+
+} // namespace bx
diff --git a/3rdparty/bx/include/bx/os.h b/3rdparty/bx/include/bx/os.h
index 78349ddab4b..d2639756198 100644
--- a/3rdparty/bx/include/bx/os.h
+++ b/3rdparty/bx/include/bx/os.h
@@ -10,57 +10,6 @@
#include "debug.h"
#include <sys/stat.h>
-#if BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT
-# include <windows.h>
-# include <psapi.h>
-#elif BX_PLATFORM_ANDROID \
- || BX_PLATFORM_EMSCRIPTEN \
- || BX_PLATFORM_BSD \
- || BX_PLATFORM_HURD \
- || BX_PLATFORM_IOS \
- || BX_PLATFORM_LINUX \
- || BX_PLATFORM_NACL \
- || BX_PLATFORM_OSX \
- || BX_PLATFORM_PS4 \
- || BX_PLATFORM_RPI \
- || BX_PLATFORM_STEAMLINK
-# include <sched.h> // sched_yield
-# if BX_PLATFORM_BSD \
- || BX_PLATFORM_IOS \
- || BX_PLATFORM_NACL \
- || BX_PLATFORM_OSX \
- || BX_PLATFORM_PS4 \
- || BX_PLATFORM_STEAMLINK
-# include <pthread.h> // mach_port_t
-# endif // BX_PLATFORM_*
-
-# include <time.h> // nanosleep
-# if !BX_PLATFORM_PS4 && !BX_PLATFORM_NACL
-# include <dlfcn.h> // dlopen, dlclose, dlsym
-# endif // !BX_PLATFORM_PS4 && !BX_PLATFORM_NACL
-
-# if BX_PLATFORM_ANDROID
-# include <malloc.h> // mallinfo
-# elif BX_PLATFORM_LINUX \
- || BX_PLATFORM_RPI \
- || BX_PLATFORM_STEAMLINK
-# include <unistd.h> // syscall
-# include <sys/syscall.h>
-# elif BX_PLATFORM_OSX
-# include <mach/mach.h> // mach_task_basic_info
-# elif BX_PLATFORM_HURD
-# include <pthread/pthread.h> // pthread_self
-# elif BX_PLATFORM_ANDROID
-# include "debug.h" // getTid is not implemented...
-# endif // BX_PLATFORM_ANDROID
-#endif // BX_PLATFORM_
-
-#if BX_CRT_MSVC
-# include <direct.h> // _getcwd
-#else
-# include <unistd.h> // getcwd
-#endif // BX_CRT_MSVC
-
#if BX_PLATFORM_OSX
# define BX_DL_EXT "dylib"
#elif BX_PLATFORM_WINDOWS
@@ -71,241 +20,6 @@
namespace bx
{
- inline void sleep(uint32_t _ms)
- {
-#if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360
- ::Sleep(_ms);
-#elif BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT
- BX_UNUSED(_ms);
- debugOutput("sleep is not implemented"); debugBreak();
-#else
- timespec req = {(time_t)_ms/1000, (long)((_ms%1000)*1000000)};
- timespec rem = {0, 0};
- ::nanosleep(&req, &rem);
-#endif // BX_PLATFORM_
- }
-
- inline void yield()
- {
-#if BX_PLATFORM_WINDOWS
- ::SwitchToThread();
-#elif BX_PLATFORM_XBOX360
- ::Sleep(0);
-#elif BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT
- debugOutput("yield is not implemented"); debugBreak();
-#else
- ::sched_yield();
-#endif // BX_PLATFORM_
- }
-
- inline uint32_t getTid()
- {
-#if BX_PLATFORM_WINDOWS
- return ::GetCurrentThreadId();
-#elif BX_PLATFORM_LINUX || BX_PLATFORM_RPI || BX_PLATFORM_STEAMLINK
- return (pid_t)::syscall(SYS_gettid);
-#elif BX_PLATFORM_IOS || BX_PLATFORM_OSX
- return (mach_port_t)::pthread_mach_thread_np(pthread_self() );
-#elif BX_PLATFORM_BSD || BX_PLATFORM_NACL
- // Casting __nc_basic_thread_data*... need better way to do this.
- return *(uint32_t*)::pthread_self();
-#elif BX_PLATFORM_HURD
- return (pthread_t)::pthread_self();
-#else
-//# pragma message "not implemented."
- debugOutput("getTid is not implemented"); debugBreak();
- return 0;
-#endif //
- }
-
- inline size_t getProcessMemoryUsed()
- {
-#if BX_PLATFORM_ANDROID
- struct mallinfo mi = mallinfo();
- return mi.uordblks;
-#elif BX_PLATFORM_LINUX || BX_PLATFORM_HURD
- FILE* file = fopen("/proc/self/statm", "r");
- if (NULL == file)
- {
- return 0;
- }
-
- long pages = 0;
- int items = fscanf(file, "%*s%ld", &pages);
- fclose(file);
- return 1 == items
- ? pages * sysconf(_SC_PAGESIZE)
- : 0
- ;
-#elif BX_PLATFORM_OSX
-# if defined(MACH_TASK_BASIC_INFO)
- mach_task_basic_info info;
- mach_msg_type_number_t infoCount = MACH_TASK_BASIC_INFO_COUNT;
-
- int const result = task_info(mach_task_self()
- , MACH_TASK_BASIC_INFO
- , (task_info_t)&info
- , &infoCount
- );
-# else // MACH_TASK_BASIC_INFO
- task_basic_info info;
- mach_msg_type_number_t infoCount = TASK_BASIC_INFO_COUNT;
-
- int const result = task_info(mach_task_self()
- , TASK_BASIC_INFO
- , (task_info_t)&info
- , &infoCount
- );
-# endif // MACH_TASK_BASIC_INFO
- if (KERN_SUCCESS != result)
- {
- return 0;
- }
-
- return info.resident_size;
-#elif BX_PLATFORM_WINDOWS
- PROCESS_MEMORY_COUNTERS pmc;
- GetProcessMemoryInfo(GetCurrentProcess()
- , &pmc
- , sizeof(pmc)
- );
- return pmc.WorkingSetSize;
-#else
- return 0;
-#endif // BX_PLATFORM_*
- }
-
- inline void* dlopen(const char* _filePath)
- {
-#if BX_PLATFORM_WINDOWS
- return (void*)::LoadLibraryA(_filePath);
-#elif BX_PLATFORM_EMSCRIPTEN \
- || BX_PLATFORM_NACL \
- || BX_PLATFORM_PS4 \
- || BX_PLATFORM_XBOXONE \
- || BX_PLATFORM_WINRT
- BX_UNUSED(_filePath);
- return NULL;
-#else
- return ::dlopen(_filePath, RTLD_LOCAL|RTLD_LAZY);
-#endif // BX_PLATFORM_
- }
-
- inline void dlclose(void* _handle)
- {
-#if BX_PLATFORM_WINDOWS
- ::FreeLibrary( (HMODULE)_handle);
-#elif BX_PLATFORM_EMSCRIPTEN \
- || BX_PLATFORM_NACL \
- || BX_PLATFORM_PS4 \
- || BX_PLATFORM_XBOXONE \
- || BX_PLATFORM_WINRT
- BX_UNUSED(_handle);
-#else
- ::dlclose(_handle);
-#endif // BX_PLATFORM_
- }
-
- inline void* dlsym(void* _handle, const char* _symbol)
- {
-#if BX_PLATFORM_WINDOWS
- return (void*)::GetProcAddress( (HMODULE)_handle, _symbol);
-#elif BX_PLATFORM_EMSCRIPTEN \
- || BX_PLATFORM_NACL \
- || BX_PLATFORM_PS4 \
- || BX_PLATFORM_XBOXONE \
- || BX_PLATFORM_WINRT
- BX_UNUSED(_handle, _symbol);
- return NULL;
-#else
- return ::dlsym(_handle, _symbol);
-#endif // BX_PLATFORM_
- }
-
- inline bool getenv(const char* _name, char* _out, uint32_t* _inOutSize)
- {
-#if BX_PLATFORM_WINDOWS
- DWORD len = ::GetEnvironmentVariableA(_name, _out, *_inOutSize);
- bool result = len != 0 && len < *_inOutSize;
- *_inOutSize = len;
- return result;
-#elif BX_PLATFORM_PS4 \
- || BX_PLATFORM_XBOXONE \
- || BX_PLATFORM_WINRT
- BX_UNUSED(_name, _out, _inOutSize);
- return false;
-#else
- const char* ptr = ::getenv(_name);
- uint32_t len = 0;
- if (NULL != ptr)
- {
- len = (uint32_t)strlen(ptr);
- }
- bool result = len != 0 && len < *_inOutSize;
- if (len < *_inOutSize)
- {
- strcpy(_out, ptr);
- }
-
- *_inOutSize = len;
- return result;
-#endif // BX_PLATFORM_
- }
-
- inline void setenv(const char* _name, const char* _value)
- {
-#if BX_PLATFORM_WINDOWS
- ::SetEnvironmentVariableA(_name, _value);
-#elif BX_PLATFORM_PS4 \
- || BX_PLATFORM_XBOXONE \
- || BX_PLATFORM_WINRT
- BX_UNUSED(_name, _value);
-#else
- ::setenv(_name, _value, 1);
-#endif // BX_PLATFORM_
- }
-
- inline void unsetenv(const char* _name)
- {
-#if BX_PLATFORM_WINDOWS
- ::SetEnvironmentVariableA(_name, NULL);
-#elif BX_PLATFORM_PS4 \
- || BX_PLATFORM_XBOXONE \
- || BX_PLATFORM_WINRT
- BX_UNUSED(_name);
-#else
- ::unsetenv(_name);
-#endif // BX_PLATFORM_
- }
-
- inline int chdir(const char* _path)
- {
-#if BX_PLATFORM_PS4 \
- || BX_PLATFORM_XBOXONE \
- || BX_PLATFORM_WINRT
- BX_UNUSED(_path);
- return -1;
-#elif BX_CRT_MSVC
- return ::_chdir(_path);
-#else
- return ::chdir(_path);
-#endif // BX_COMPILER_
- }
-
- inline char* pwd(char* _buffer, uint32_t _size)
- {
-#if BX_PLATFORM_PS4 \
- || BX_PLATFORM_XBOXONE \
- || BX_PLATFORM_WINRT
- BX_UNUSED(_buffer, _size);
- return NULL;
-#elif BX_CRT_MSVC
- return ::_getcwd(_buffer, (int)_size);
-#else
- return ::getcwd(_buffer, _size);
-#endif // BX_COMPILER_
- }
-
struct FileInfo
{
enum Enum
@@ -320,50 +34,50 @@ namespace bx
Enum m_type;
};
- inline bool stat(const char* _filePath, FileInfo& _fileInfo)
- {
- _fileInfo.m_size = 0;
- _fileInfo.m_type = FileInfo::Count;
+ ///
+ void sleep(uint32_t _ms);
-#if BX_COMPILER_MSVC
- struct ::_stat64 st;
- int32_t result = ::_stat64(_filePath, &st);
+ ///
+ void yield();
- if (0 != result)
- {
- return false;
- }
+ ///
+ uint32_t getTid();
- if (0 != (st.st_mode & _S_IFREG) )
- {
- _fileInfo.m_type = FileInfo::Regular;
- }
- else if (0 != (st.st_mode & _S_IFDIR) )
- {
- _fileInfo.m_type = FileInfo::Directory;
- }
-#else
- struct ::stat st;
- int32_t result = ::stat(_filePath, &st);
- if (0 != result)
- {
- return false;
- }
+ ///
+ size_t getProcessMemoryUsed();
- if (0 != (st.st_mode & S_IFREG) )
- {
- _fileInfo.m_type = FileInfo::Regular;
- }
- else if (0 != (st.st_mode & S_IFDIR) )
- {
- _fileInfo.m_type = FileInfo::Directory;
- }
-#endif // BX_COMPILER_MSVC
+ ///
+ void* dlopen(const char* _filePath);
+
+ ///
+ void dlclose(void* _handle);
+
+ ///
+ void* dlsym(void* _handle, const char* _symbol);
+
+ ///
+ bool getenv(const char* _name, char* _out, uint32_t* _inOutSize);
+
+ ///
+ void setenv(const char* _name, const char* _value);
+
+ ///
+ void unsetenv(const char* _name);
+
+ ///
+ int chdir(const char* _path);
+
+ ///
+ char* pwd(char* _buffer, uint32_t _size);
+
+ ///
+ bool getTempPath(char* _out, uint32_t* _inOutSize);
- _fileInfo.m_size = st.st_size;
+ ///
+ bool stat(const char* _filePath, FileInfo& _fileInfo);
- return true;
- }
+ ///
+ void* exec(const char* const* _argv);
} // namespace bx
diff --git a/3rdparty/bx/include/bx/pixelformat.h b/3rdparty/bx/include/bx/pixelformat.h
new file mode 100644
index 00000000000..5b2bf565803
--- /dev/null
+++ b/3rdparty/bx/include/bx/pixelformat.h
@@ -0,0 +1,243 @@
+/*
+ * Copyright 2011-2017 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ */
+
+#ifndef BX_PIXEL_FORMAT_H_HEADER_GUARD
+#define BX_PIXEL_FORMAT_H_HEADER_GUARD
+
+#include <bx/fpumath.h>
+#include <bx/uint32_t.h>
+
+namespace bx
+{
+ struct EncodingType
+ {
+ enum Enum
+ {
+ Unorm,
+ Int,
+ Uint,
+ Float,
+ Snorm,
+
+ Count
+ };
+ };
+
+ typedef void (*PackFn)(void*, const float*);
+ typedef void (*UnpackFn)(float*, const void*);
+
+ ///
+ uint32_t toUnorm(float _value, float _scale);
+
+ ///
+ float fromUnorm(uint32_t _value, float _scale);
+
+ ///
+ int32_t toSnorm(float _value, float _scale);
+
+ ///
+ float fromSnorm(int32_t _value, float _scale);
+
+ // R8
+ void packR8(void* _dst, const float* _src);
+ void unpackR8(float* _dst, const void* _src);
+
+ // R8S
+ void packR8S(void* _dst, const float* _src);
+ void unpackR8S(float* _dst, const void* _src);
+
+ // R8I
+ void packR8I(void* _dst, const float* _src);
+ void unpackR8I(float* _dst, const void* _src);
+
+ // R8U
+ void packR8U(void* _dst, const float* _src);
+ void unpackR8U(float* _dst, const void* _src);
+
+ // RG8
+ void packRg8(void* _dst, const float* _src);
+ void unpackRg8(float* _dst, const void* _src);
+
+ // RG8S
+ void packRg8S(void* _dst, const float* _src);
+ void unpackRg8S(float* _dst, const void* _src);
+
+ // RG8I
+ void packRg8I(void* _dst, const float* _src);
+ void unpackRg8I(float* _dst, const void* _src);
+
+ // RG8U
+ void packRg8U(void* _dst, const float* _src);
+ void unpackRg8U(float* _dst, const void* _src);
+
+ // RGB8
+ void packRgb8(void* _dst, const float* _src);
+ void unpackRgb8(float* _dst, const void* _src);
+
+ // RGB8S
+ void packRgb8S(void* _dst, const float* _src);
+ void unpackRgb8S(float* _dst, const void* _src);
+
+ // RGB8I
+ void packRgb8I(void* _dst, const float* _src);
+ void unpackRgb8I(float* _dst, const void* _src);
+
+ // RGB8U
+ void packRgb8U(void* _dst, const float* _src);
+ void unpackRgb8U(float* _dst, const void* _src);
+
+ // RGBA8
+ void packRgba8(void* _dst, const float* _src);
+ void unpackRgba8(float* _dst, const void* _src);
+
+ // BGRA8
+ void packBgra8(void* _dst, const float* _src);
+ void unpackBgra8(float* _dst, const void* _src);
+
+ // RGBA8S
+ void packRgba8S(void* _dst, const float* _src);
+ void unpackRgba8S(float* _dst, const void* _src);
+
+ // RGBA8I
+ void packRgba8I(void* _dst, const float* _src);
+ void unpackRgba8I(float* _dst, const void* _src);
+
+ // RGBA8U
+ void packRgba8U(void* _dst, const float* _src);
+ void unpackRgba8U(float* _dst, const void* _src);
+
+ // R16
+ void packR16(void* _dst, const float* _src);
+ void unpackR16(float* _dst, const void* _src);
+
+ // R16S
+ void packR16S(void* _dst, const float* _src);
+ void unpackR16S(float* _dst, const void* _src);
+
+ // R16I
+ void packR16I(void* _dst, const float* _src);
+ void unpackR16I(float* _dst, const void* _src);
+
+ // R16U
+ void packR16U(void* _dst, const float* _src);
+ void unpackR16U(float* _dst, const void* _src);
+
+ // R16F
+ void packR16F(void* _dst, const float* _src);
+ void unpackR16F(float* _dst, const void* _src);
+
+ // RG16
+ void packRg16(void* _dst, const float* _src);
+ void unpackRg16(float* _dst, const void* _src);
+
+ // RG16S
+ void packRg16S(void* _dst, const float* _src);
+ void unpackRg16S(float* _dst, const void* _src);
+
+ // RG16I
+ void packRg16I(void* _dst, const float* _src);
+ void unpackRg16I(float* _dst, const void* _src);
+
+ // RG16U
+ void packRg16U(void* _dst, const float* _src);
+ void unpackRg16U(float* _dst, const void* _src);
+
+ // RG16F
+ void packRg16F(void* _dst, const float* _src);
+ void unpackRg16F(float* _dst, const void* _src);
+
+ // RGBA16
+ void packRgba16(void* _dst, const float* _src);
+ void unpackRgba16(float* _dst, const void* _src);
+
+ // RGBA16S
+ void packRgba16S(void* _dst, const float* _src);
+ void unpackRgba16S(float* _dst, const void* _src);
+
+ // RGBA16I
+ void packRgba16I(void* _dst, const float* _src);
+ void unpackRgba16I(float* _dst, const void* _src);
+
+ // RGBA16U
+ void packRgba16U(void* _dst, const float* _src);
+ void unpackRgba16U(float* _dst, const void* _src);
+
+ // RGBA16F
+ void packRgba16F(void* _dst, const float* _src);
+ void unpackRgba16F(float* _dst, const void* _src);
+
+ // R32I
+ void packR32I(void* _dst, const float* _src);
+ void unpackR32I(float* _dst, const void* _src);
+
+ // R32U
+ void packR32U(void* _dst, const float* _src);
+ void unpackR32U(float* _dst, const void* _src);
+
+ // R32F
+ void packR32F(void* _dst, const float* _src);
+ void unpackR32F(float* _dst, const void* _src);
+
+ // RG32I
+ void packRg32I(void* _dst, const float* _src);
+ void unpackRg32I(float* _dst, const void* _src);
+
+ // RG32U
+ void packRg32U(void* _dst, const float* _src);
+ void unpackRg32U(float* _dst, const void* _src);
+
+ // RGB9E5F
+ void packRgb9E5F(void* _dst, const float* _src);
+ void unpackRgb9E5F(float* _dst, const void* _src);
+
+ // RGBA32I
+ void packRgba32I(void* _dst, const float* _src);
+ void unpackRgba32I(float* _dst, const void* _src);
+
+ // RGBA32U
+ void packRgba32U(void* _dst, const float* _src);
+ void unpackRgba32U(float* _dst, const void* _src);
+
+ // RGBA32F
+ void packRgba32F(void* _dst, const float* _src);
+ void unpackRgba32F(float* _dst, const void* _src);
+
+ // R5G6B5
+ void packR5G6B5(void* _dst, const float* _src);
+ void unpackR5G6B5(float* _dst, const void* _src);
+
+ // RGBA4
+ void packRgba4(void* _dst, const float* _src);
+ void unpackRgba4(float* _dst, const void* _src);
+
+ // RGBA4
+ void packBgra4(void* _dst, const float* _src);
+ void unpackBgra4(float* _dst, const void* _src);
+
+ // RGB5A1
+ void packRgb5a1(void* _dst, const float* _src);
+ void unpackRgb5a1(float* _dst, const void* _src);
+
+ // BGR5A1
+ void packBgr5a1(void* _dst, const float* _src);
+ void unpackBgr5a1(float* _dst, const void* _src);
+
+ // RGB10A2
+ void packRgb10A2(void* _dst, const float* _src);
+ void unpackRgb10A2(float* _dst, const void* _src);
+
+ // R11G11B10F
+ void packR11G11B10F(void* _dst, const float* _src);
+ void unpackR11G11B10F(float* _dst, const void* _src);
+
+ // RG32F
+ void packRg32F(void* _dst, const float* _src);
+ void unpackRg32F(float* _dst, const void* _src);
+
+} // namespace bx
+
+#include "pixelformat.inl"
+
+#endif // BX_PIXEL_FORMAT_H_HEADER_GUARD
diff --git a/3rdparty/bx/include/bx/pixelformat.inl b/3rdparty/bx/include/bx/pixelformat.inl
new file mode 100644
index 00000000000..be48c85d931
--- /dev/null
+++ b/3rdparty/bx/include/bx/pixelformat.inl
@@ -0,0 +1,945 @@
+/*
+ * Copyright 2010-2016 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ */
+
+#ifndef BX_PIXEL_FORMAT_H_HEADER_GUARD
+# error "Must be included from bx/pixelformat.h"
+#endif // BX_PIXEL_FORMAT_H_HEADER_GUARD
+
+namespace bx
+{
+ inline uint32_t toUnorm(float _value, float _scale)
+ {
+ return uint32_t(fround(fsaturate(_value) * _scale) );
+ }
+
+ inline float fromUnorm(uint32_t _value, float _scale)
+ {
+ return float(_value) / _scale;
+ }
+
+ inline int32_t toSnorm(float _value, float _scale)
+ {
+ return int32_t(fround(
+ fclamp(_value, -1.0f, 1.0f) * _scale)
+ );
+ }
+
+ inline float fromSnorm(int32_t _value, float _scale)
+ {
+ return fmax(-1.0f, float(_value) / _scale);
+ }
+
+ // R8
+ inline void packR8(void* _dst, const float* _src)
+ {
+ uint8_t* dst = (uint8_t*)_dst;
+ dst[0] = uint8_t(toUnorm(_src[0], 255.0f) );
+ }
+
+ inline void unpackR8(float* _dst, const void* _src)
+ {
+ const uint8_t* src = (const uint8_t*)_src;
+ _dst[0] = fromUnorm(src[0], 255.0f);
+ _dst[1] = 0.0f;
+ _dst[2] = 0.0f;
+ _dst[3] = 1.0f;
+ }
+
+ // R8S
+ inline void packR8S(void* _dst, const float* _src)
+ {
+ int8_t* dst = (int8_t*)_dst;
+ dst[0] = int8_t(toSnorm(_src[0], 127.0f) );
+ }
+
+ inline void unpackR8S(float* _dst, const void* _src)
+ {
+ const int8_t* src = (const int8_t*)_src;
+ _dst[0] = fromSnorm(src[0], 127.0f);
+ _dst[1] = 0.0f;
+ _dst[2] = 0.0f;
+ _dst[3] = 1.0f;
+ }
+
+ // R8I
+ inline void packR8I(void* _dst, const float* _src)
+ {
+ int8_t* dst = (int8_t*)_dst;
+ dst[0] = int8_t(_src[0]);
+ }
+
+ inline void unpackR8I(float* _dst, const void* _src)
+ {
+ const int8_t* src = (const int8_t*)_src;
+ _dst[0] = float(src[0]);
+ _dst[1] = 0.0f;
+ _dst[2] = 0.0f;
+ _dst[3] = 1.0f;
+ }
+
+ // R8U
+ inline void packR8U(void* _dst, const float* _src)
+ {
+ uint8_t* dst = (uint8_t*)_dst;
+ dst[0] = uint8_t(_src[0]);
+ }
+
+ inline void unpackR8U(float* _dst, const void* _src)
+ {
+ const uint8_t* src = (const uint8_t*)_src;
+ _dst[0] = float(src[0]);
+ _dst[1] = 0.0f;
+ _dst[2] = 0.0f;
+ _dst[3] = 1.0f;
+ }
+
+ // RG8
+ inline void packRg8(void* _dst, const float* _src)
+ {
+ uint8_t* dst = (uint8_t*)_dst;
+ dst[0] = uint8_t(toUnorm(_src[0], 255.0f) );
+ dst[1] = uint8_t(toUnorm(_src[1], 255.0f) );
+ }
+
+ inline void unpackRg8(float* _dst, const void* _src)
+ {
+ const uint8_t* src = (const uint8_t*)_src;
+ _dst[0] = fromUnorm(src[0], 255.0f);
+ _dst[1] = fromUnorm(src[1], 255.0f);
+ _dst[2] = 0.0f;
+ _dst[3] = 1.0f;
+ }
+
+ // RG8S
+ inline void packRg8S(void* _dst, const float* _src)
+ {
+ int8_t* dst = (int8_t*)_dst;
+ dst[0] = int8_t(toSnorm(_src[0], 127.0f) );
+ dst[1] = int8_t(toSnorm(_src[1], 127.0f) );
+ }
+
+ inline void unpackRg8S(float* _dst, const void* _src)
+ {
+ const int8_t* src = (const int8_t*)_src;
+ _dst[0] = fromSnorm(src[0], 127.0f);
+ _dst[1] = fromSnorm(src[1], 127.0f);
+ _dst[2] = 0.0f;
+ _dst[3] = 1.0f;
+ }
+
+ // RG8I
+ inline void packRg8I(void* _dst, const float* _src)
+ {
+ int8_t* dst = (int8_t*)_dst;
+ dst[0] = int8_t(_src[0]);
+ dst[1] = int8_t(_src[1]);
+ }
+
+ inline void unpackRg8I(float* _dst, const void* _src)
+ {
+ const int8_t* src = (const int8_t*)_src;
+ _dst[0] = float(src[0]);
+ _dst[1] = float(src[1]);
+ _dst[2] = 0.0f;
+ _dst[3] = 1.0f;
+ }
+
+ // RG8U
+ inline void packRg8U(void* _dst, const float* _src)
+ {
+ uint8_t* dst = (uint8_t*)_dst;
+ dst[0] = uint8_t(_src[0]);
+ dst[1] = uint8_t(_src[1]);
+ }
+
+ inline void unpackRg8U(float* _dst, const void* _src)
+ {
+ const uint8_t* src = (const uint8_t*)_src;
+ _dst[0] = float(src[0]);
+ _dst[1] = float(src[1]);
+ _dst[2] = 0.0f;
+ _dst[3] = 1.0f;
+ }
+
+ // RGB8
+ inline void packRgb8(void* _dst, const float* _src)
+ {
+ uint8_t* dst = (uint8_t*)_dst;
+ dst[0] = uint8_t(toUnorm(_src[0], 255.0f) );
+ dst[1] = uint8_t(toUnorm(_src[1], 255.0f) );
+ dst[2] = uint8_t(toUnorm(_src[2], 255.0f) );
+ }
+
+ inline void unpackRgb8(float* _dst, const void* _src)
+ {
+ const uint8_t* src = (const uint8_t*)_src;
+ _dst[0] = fromUnorm(src[0], 255.0f);
+ _dst[1] = fromUnorm(src[1], 255.0f);
+ _dst[2] = fromUnorm(src[2], 255.0f);
+ _dst[3] = 1.0f;
+ }
+
+ // RGB8S
+ inline void packRgb8S(void* _dst, const float* _src)
+ {
+ int8_t* dst = (int8_t*)_dst;
+ dst[0] = int8_t(toSnorm(_src[0], 127.0f) );
+ dst[1] = int8_t(toSnorm(_src[1], 127.0f) );
+ dst[2] = int8_t(toSnorm(_src[2], 127.0f) );
+ }
+
+ inline void unpackRgb8S(float* _dst, const void* _src)
+ {
+ const int8_t* src = (const int8_t*)_src;
+ _dst[0] = fromSnorm(src[0], 127.0f);
+ _dst[1] = fromSnorm(src[1], 127.0f);
+ _dst[2] = fromSnorm(src[2], 127.0f);
+ _dst[3] = 1.0f;
+ }
+
+ // RGB8I
+ inline void packRgb8I(void* _dst, const float* _src)
+ {
+ int8_t* dst = (int8_t*)_dst;
+ dst[0] = int8_t(_src[0]);
+ dst[1] = int8_t(_src[1]);
+ dst[2] = int8_t(_src[2]);
+ }
+
+ inline void unpackRgb8I(float* _dst, const void* _src)
+ {
+ const int8_t* src = (const int8_t*)_src;
+ _dst[0] = float(src[0]);
+ _dst[1] = float(src[1]);
+ _dst[2] = float(src[2]);
+ _dst[3] = 1.0f;
+ }
+
+ // RGB8U
+ inline void packRgb8U(void* _dst, const float* _src)
+ {
+ uint8_t* dst = (uint8_t*)_dst;
+ dst[0] = uint8_t(_src[0]);
+ dst[1] = uint8_t(_src[1]);
+ dst[2] = uint8_t(_src[2]);
+ }
+
+ inline void unpackRgb8U(float* _dst, const void* _src)
+ {
+ const uint8_t* src = (const uint8_t*)_src;
+ _dst[0] = float(src[0]);
+ _dst[1] = float(src[1]);
+ _dst[2] = float(src[2]);
+ _dst[3] = 1.0f;
+ }
+
+ // BGRA8
+ inline void packBgra8(void* _dst, const float* _src)
+ {
+ uint8_t* dst = (uint8_t*)_dst;
+ dst[2] = uint8_t(toUnorm(_src[0], 255.0f) );
+ dst[1] = uint8_t(toUnorm(_src[1], 255.0f) );
+ dst[0] = uint8_t(toUnorm(_src[2], 255.0f) );
+ dst[3] = uint8_t(toUnorm(_src[3], 255.0f) );
+ }
+
+ inline void unpackBgra8(float* _dst, const void* _src)
+ {
+ const uint8_t* src = (const uint8_t*)_src;
+ _dst[0] = fromUnorm(src[2], 255.0f);
+ _dst[1] = fromUnorm(src[1], 255.0f);
+ _dst[2] = fromUnorm(src[0], 255.0f);
+ _dst[3] = fromUnorm(src[3], 255.0f);
+ }
+
+ // RGBA8
+ inline void packRgba8(void* _dst, const float* _src)
+ {
+ uint8_t* dst = (uint8_t*)_dst;
+ dst[0] = uint8_t(toUnorm(_src[0], 255.0f) );
+ dst[1] = uint8_t(toUnorm(_src[1], 255.0f) );
+ dst[2] = uint8_t(toUnorm(_src[2], 255.0f) );
+ dst[3] = uint8_t(toUnorm(_src[3], 255.0f) );
+ }
+
+ inline void unpackRgba8(float* _dst, const void* _src)
+ {
+ const uint8_t* src = (const uint8_t*)_src;
+ _dst[0] = fromUnorm(src[0], 255.0f);
+ _dst[1] = fromUnorm(src[1], 255.0f);
+ _dst[2] = fromUnorm(src[2], 255.0f);
+ _dst[3] = fromUnorm(src[3], 255.0f);
+ }
+
+ // RGBA8S
+ inline void packRgba8S(void* _dst, const float* _src)
+ {
+ int8_t* dst = (int8_t*)_dst;
+ dst[0] = int8_t(toSnorm(_src[0], 127.0f) );
+ dst[1] = int8_t(toSnorm(_src[1], 127.0f) );
+ dst[2] = int8_t(toSnorm(_src[2], 127.0f) );
+ dst[3] = int8_t(toSnorm(_src[3], 127.0f) );
+ }
+
+ inline void unpackRgba8S(float* _dst, const void* _src)
+ {
+ const int8_t* src = (const int8_t*)_src;
+ _dst[0] = fromSnorm(src[0], 127.0f);
+ _dst[1] = fromSnorm(src[1], 127.0f);
+ _dst[2] = fromSnorm(src[2], 127.0f);
+ _dst[3] = fromSnorm(src[3], 127.0f);
+ }
+
+ // RGBA8I
+ inline void packRgba8I(void* _dst, const float* _src)
+ {
+ int8_t* dst = (int8_t*)_dst;
+ dst[0] = int8_t(_src[0]);
+ dst[1] = int8_t(_src[1]);
+ dst[2] = int8_t(_src[2]);
+ dst[3] = int8_t(_src[3]);
+ }
+
+ inline void unpackRgba8I(float* _dst, const void* _src)
+ {
+ const int8_t* src = (const int8_t*)_src;
+ _dst[0] = float(src[0]);
+ _dst[1] = float(src[1]);
+ _dst[2] = float(src[2]);
+ _dst[3] = float(src[3]);
+ }
+
+ // RGBA8U
+ inline void packRgba8U(void* _dst, const float* _src)
+ {
+ uint8_t* dst = (uint8_t*)_dst;
+ dst[0] = uint8_t(_src[0]);
+ dst[1] = uint8_t(_src[1]);
+ dst[2] = uint8_t(_src[2]);
+ dst[3] = uint8_t(_src[3]);
+ }
+
+ inline void unpackRgba8U(float* _dst, const void* _src)
+ {
+ const uint8_t* src = (const uint8_t*)_src;
+ _dst[0] = float(src[0]);
+ _dst[1] = float(src[1]);
+ _dst[2] = float(src[2]);
+ _dst[3] = float(src[3]);
+ }
+
+ // R16
+ inline void packR16(void* _dst, const float* _src)
+ {
+ uint16_t* dst = (uint16_t*)_dst;
+ dst[0] = uint16_t(toUnorm(_src[0], 65535.0f) );
+ }
+
+ inline void unpackR16(float* _dst, const void* _src)
+ {
+ const uint16_t* src = (const uint16_t*)_src;
+ _dst[0] = fromUnorm(src[0], 65535.0f);
+ _dst[1] = 0.0f;
+ _dst[2] = 0.0f;
+ _dst[3] = 1.0f;
+ }
+
+ // R16S
+ inline void packR16S(void* _dst, const float* _src)
+ {
+ int16_t* dst = (int16_t*)_dst;
+ dst[0] = int16_t(toSnorm(_src[0], 32767.0f) );
+ }
+
+ inline void unpackR16S(float* _dst, const void* _src)
+ {
+ const int16_t* src = (const int16_t*)_src;
+ _dst[0] = fromSnorm(src[0], 32767.0f);
+ _dst[1] = 0.0f;
+ _dst[2] = 0.0f;
+ _dst[3] = 1.0f;
+ }
+
+ // R16I
+ inline void packR16I(void* _dst, const float* _src)
+ {
+ int16_t* dst = (int16_t*)_dst;
+ dst[0] = int16_t(_src[0]);
+ }
+
+ inline void unpackR16I(float* _dst, const void* _src)
+ {
+ const int16_t* src = (const int16_t*)_src;
+ _dst[0] = float(src[0]);
+ _dst[1] = 0.0f;
+ _dst[2] = 0.0f;
+ _dst[3] = 1.0f;
+ }
+
+ // R16U
+ inline void packR16U(void* _dst, const float* _src)
+ {
+ uint16_t* dst = (uint16_t*)_dst;
+ dst[0] = uint16_t(_src[0]);
+ }
+
+ inline void unpackR16U(float* _dst, const void* _src)
+ {
+ const uint16_t* src = (const uint16_t*)_src;
+ _dst[0] = float(src[0]);
+ }
+
+ // R16F
+ inline void packR16F(void* _dst, const float* _src)
+ {
+ uint16_t* dst = (uint16_t*)_dst;
+ dst[0] = halfFromFloat(_src[0]);
+ }
+
+ inline void unpackR16F(float* _dst, const void* _src)
+ {
+ const uint16_t* src = (const uint16_t*)_src;
+ _dst[0] = halfToFloat(src[0]);
+ _dst[1] = 0.0f;
+ _dst[2] = 0.0f;
+ _dst[3] = 1.0f;
+ }
+
+ // RG16
+ inline void packRg16(void* _dst, const float* _src)
+ {
+ uint16_t* dst = (uint16_t*)_dst;
+ dst[0] = uint16_t(toUnorm(_src[0], 65535.0f) );
+ dst[1] = uint16_t(toUnorm(_src[1], 65535.0f) );
+ }
+
+ inline void unpackRg16(float* _dst, const void* _src)
+ {
+ const uint16_t* src = (const uint16_t*)_src;
+ _dst[0] = fromUnorm(src[0], 65535.0f);
+ _dst[1] = fromUnorm(src[1], 65535.0f);
+ _dst[2] = 0.0f;
+ _dst[3] = 1.0f;
+ }
+
+ // RG16S
+ inline void packRg16S(void* _dst, const float* _src)
+ {
+ int16_t* dst = (int16_t*)_dst;
+ dst[0] = int16_t(toSnorm(_src[0], 32767.0f) );
+ dst[1] = int16_t(toSnorm(_src[1], 32767.0f) );
+ }
+
+ inline void unpackRg16S(float* _dst, const void* _src)
+ {
+ const int16_t* src = (const int16_t*)_src;
+ _dst[0] = fromSnorm(src[0], 32767.0f);
+ _dst[1] = fromSnorm(src[1], 32767.0f);
+ _dst[2] = 0.0f;
+ _dst[3] = 1.0f;
+ }
+
+ // RG16I
+ inline void packRg16I(void* _dst, const float* _src)
+ {
+ int16_t* dst = (int16_t*)_dst;
+ dst[0] = int16_t(_src[0]);
+ dst[1] = int16_t(_src[1]);
+ }
+
+ inline void unpackRg16I(float* _dst, const void* _src)
+ {
+ const int16_t* src = (const int16_t*)_src;
+ _dst[0] = float(src[0]);
+ _dst[1] = float(src[1]);
+ _dst[2] = 0.0f;
+ _dst[3] = 1.0f;
+ }
+
+ // RG16U
+ inline void packRg16U(void* _dst, const float* _src)
+ {
+ uint16_t* dst = (uint16_t*)_dst;
+ dst[0] = uint16_t(_src[0]);
+ dst[1] = uint16_t(_src[1]);
+ }
+
+ inline void unpackRg16U(float* _dst, const void* _src)
+ {
+ const uint16_t* src = (const uint16_t*)_src;
+ _dst[0] = float(src[0]);
+ _dst[1] = float(src[1]);
+ _dst[2] = 0.0f;
+ _dst[3] = 1.0f;
+ }
+
+ // RG16F
+ inline void packRg16F(void* _dst, const float* _src)
+ {
+ uint16_t* dst = (uint16_t*)_dst;
+ dst[0] = halfFromFloat(_src[0]);
+ dst[1] = halfFromFloat(_src[1]);
+ }
+
+ inline void unpackRg16F(float* _dst, const void* _src)
+ {
+ const uint16_t* src = (const uint16_t*)_src;
+ _dst[0] = halfToFloat(src[0]);
+ _dst[1] = halfToFloat(src[1]);
+ _dst[2] = 0.0f;
+ _dst[3] = 1.0f;
+ }
+
+ // RGBA16
+ inline void packRgba16(void* _dst, const float* _src)
+ {
+ uint16_t* dst = (uint16_t*)_dst;
+ dst[0] = uint16_t(toUnorm(_src[0], 65535.0f) );
+ dst[1] = uint16_t(toUnorm(_src[1], 65535.0f) );
+ dst[2] = uint16_t(toUnorm(_src[2], 65535.0f) );
+ dst[3] = uint16_t(toUnorm(_src[3], 65535.0f) );
+ }
+
+ inline void unpackRgba16(float* _dst, const void* _src)
+ {
+ const uint16_t* src = (const uint16_t*)_src;
+ _dst[0] = fromUnorm(src[0], 65535.0f);
+ _dst[1] = fromUnorm(src[1], 65535.0f);
+ _dst[2] = fromUnorm(src[2], 65535.0f);
+ _dst[3] = fromUnorm(src[3], 65535.0f);
+ }
+
+ // RGBA16S
+ inline void packRgba16S(void* _dst, const float* _src)
+ {
+ int16_t* dst = (int16_t*)_dst;
+ dst[0] = int16_t(toSnorm(_src[0], 32767.0f) );
+ dst[1] = int16_t(toSnorm(_src[1], 32767.0f) );
+ dst[2] = int16_t(toSnorm(_src[2], 32767.0f) );
+ dst[3] = int16_t(toSnorm(_src[3], 32767.0f) );
+ }
+
+ inline void unpackRgba16S(float* _dst, const void* _src)
+ {
+ const int16_t* src = (const int16_t*)_src;
+ _dst[0] = fromSnorm(src[0], 32767.0f);
+ _dst[1] = fromSnorm(src[1], 32767.0f);
+ _dst[2] = fromSnorm(src[2], 32767.0f);
+ _dst[3] = fromSnorm(src[3], 32767.0f);
+ }
+
+ // RGBA16I
+ inline void packRgba16I(void* _dst, const float* _src)
+ {
+ int16_t* dst = (int16_t*)_dst;
+ dst[0] = int16_t(_src[0]);
+ dst[1] = int16_t(_src[1]);
+ dst[2] = int16_t(_src[2]);
+ dst[3] = int16_t(_src[3]);
+ }
+
+ inline void unpackRgba16I(float* _dst, const void* _src)
+ {
+ const int16_t* src = (const int16_t*)_src;
+ _dst[0] = float(src[0]);
+ _dst[1] = float(src[1]);
+ _dst[2] = float(src[2]);
+ _dst[3] = float(src[3]);
+ }
+
+ // RGBA16U
+ inline void packRgba16U(void* _dst, const float* _src)
+ {
+ uint16_t* dst = (uint16_t*)_dst;
+ dst[0] = uint16_t(_src[0]);
+ dst[1] = uint16_t(_src[1]);
+ dst[2] = uint16_t(_src[2]);
+ dst[3] = uint16_t(_src[3]);
+ }
+
+ inline void unpackRgba16U(float* _dst, const void* _src)
+ {
+ const uint16_t* src = (const uint16_t*)_src;
+ _dst[0] = float(src[0]);
+ _dst[1] = float(src[1]);
+ _dst[2] = float(src[2]);
+ _dst[3] = float(src[3]);
+ }
+
+ // RGBA16F
+ inline void packRgba16F(void* _dst, const float* _src)
+ {
+ uint16_t* dst = (uint16_t*)_dst;
+ dst[0] = halfFromFloat(_src[0]);
+ dst[1] = halfFromFloat(_src[1]);
+ dst[2] = halfFromFloat(_src[2]);
+ dst[3] = halfFromFloat(_src[3]);
+ }
+
+ inline void unpackRgba16F(float* _dst, const void* _src)
+ {
+ const uint16_t* src = (const uint16_t*)_src;
+ _dst[0] = halfToFloat(src[0]);
+ _dst[1] = halfToFloat(src[1]);
+ _dst[2] = halfToFloat(src[2]);
+ _dst[3] = halfToFloat(src[3]);
+ }
+
+ // R24
+ inline void packR24(void* _dst, const float* _src)
+ {
+ uint8_t* dst = (uint8_t*)_dst;
+ const uint32_t rr = uint32_t(toUnorm(_src[0], 16777216.0f) );
+ dst[0] = uint8_t(rr );
+ dst[1] = uint8_t(rr>> 8);
+ dst[2] = uint8_t(rr>>16);
+ }
+
+ inline void unpackR24(float* _dst, const void* _src)
+ {
+ const uint8_t* src = (const uint8_t*)_src;
+ const uint32_t rr = 0
+ | (src[0] )
+ | (src[1]<< 8)
+ | (src[2]<<16)
+ ;
+
+ _dst[0] = fromUnorm(rr, 16777216.0f);
+ _dst[1] = 0.0f;
+ _dst[2] = 0.0f;
+ _dst[3] = 1.0f;
+ }
+
+ // R24G8
+ inline void packR24G8(void* _dst, const float* _src)
+ {
+ uint8_t* dst = (uint8_t*)_dst;
+ const uint32_t rr = uint32_t(toUnorm(_src[0], 16777216.0f) );
+ dst[0] = uint8_t(rr );
+ dst[1] = uint8_t(rr>> 8);
+ dst[2] = uint8_t(rr>>16);
+ dst[3] = uint8_t(toUnorm(_src[1], 255.0f) );
+ }
+
+ inline void unpackR24G8(float* _dst, const void* _src)
+ {
+ const uint8_t* src = (const uint8_t*)_src;
+ const uint32_t rr = 0
+ | (src[0] )
+ | (src[1]<< 8)
+ | (src[2]<<16)
+ ;
+
+ _dst[0] = fromUnorm(rr, 16777216.0f);
+ _dst[1] = fromUnorm(src[3], 255.0f);
+ _dst[2] = 0.0f;
+ _dst[3] = 1.0f;
+ }
+
+ // R32I
+ inline void packR32I(void* _dst, const float* _src)
+ {
+ memcpy(_dst, _src, 4);
+ }
+
+ inline void unpackR32I(float* _dst, const void* _src)
+ {
+ memcpy(_dst, _src, 4);
+ }
+
+ // R32U
+ inline void packR32U(void* _dst, const float* _src)
+ {
+ memcpy(_dst, _src, 4);
+ }
+
+ inline void unpackR32U(float* _dst, const void* _src)
+ {
+ memcpy(_dst, _src, 4);
+ }
+
+ // R32F
+ inline void packR32F(void* _dst, const float* _src)
+ {
+ memcpy(_dst, _src, 4);
+ }
+
+ inline void unpackR32F(float* _dst, const void* _src)
+ {
+ memcpy(_dst, _src, 4);
+ }
+
+ // RG32I
+ inline void packRg32I(void* _dst, const float* _src)
+ {
+ memcpy(_dst, _src, 8);
+ }
+
+ inline void unpackRg32I(float* _dst, const void* _src)
+ {
+ memcpy(_dst, _src, 8);
+ }
+
+ // RG32U
+ inline void packRg32U(void* _dst, const float* _src)
+ {
+ memcpy(_dst, _src, 8);
+ }
+
+ inline void unpackRg32U(float* _dst, const void* _src)
+ {
+ memcpy(_dst, _src, 8);
+ }
+
+ // RG32F
+ inline void packRg32F(void* _dst, const float* _src)
+ {
+ memcpy(_dst, _src, 8);
+ }
+
+ inline void unpackRg32F(float* _dst, const void* _src)
+ {
+ memcpy(_dst, _src, 8);
+ }
+
+ template<int32_t MantissaBits, int32_t ExpBits>
+ inline void encodeRgbE(float* _dst, const float* _src)
+ {
+ // Reference:
+ // https://www.opengl.org/registry/specs/EXT/texture_shared_exponent.txt
+ const int32_t expMax = (1<<ExpBits) - 1;
+ const int32_t expBias = (1<<(ExpBits - 1) ) - 1;
+ const float sharedExpMax = float(expMax) / float(expMax + 1) * float(1 << (expMax - expBias) );
+
+ const float rr = fclamp(_src[0], 0.0f, sharedExpMax);
+ const float gg = fclamp(_src[1], 0.0f, sharedExpMax);
+ const float bb = fclamp(_src[2], 0.0f, sharedExpMax);
+ const float max = fmax3(rr, gg, bb);
+ union { float ff; uint32_t ui; } cast = { max };
+ int32_t expShared = int32_t(uint32_imax(uint32_t(-expBias-1), ( ( (cast.ui>>23) & 0xff) - 127) ) ) + 1 + expBias;
+ float denom = fpow(2.0f, float(expShared - expBias - MantissaBits) );
+
+ if ( (1<<MantissaBits) == int32_t(fround(max/denom) ) )
+ {
+ denom *= 2.0f;
+ ++expShared;
+ }
+
+ const float invDenom = 1.0f/denom;
+ _dst[0] = fround(rr * invDenom);
+ _dst[1] = fround(gg * invDenom);
+ _dst[2] = fround(bb * invDenom);
+ _dst[3] = float(expShared);
+ }
+
+ template<int32_t MantissaBits, int32_t ExpBits>
+ inline void decodeRgbE(float* _dst, const float* _src)
+ {
+ const int32_t expBias = (1<<(ExpBits - 1) ) - 1;
+ const float exponent = _src[3]-float(expBias-MantissaBits);
+ const float scale = fpow(2.0f, exponent);
+ _dst[0] = _src[0] * scale;
+ _dst[1] = _src[1] * scale;
+ _dst[2] = _src[2] * scale;
+ }
+
+ // RGB9E5F
+ inline void packRgb9E5F(void* _dst, const float* _src)
+ {
+ float tmp[4];
+ encodeRgbE<9, 5>(tmp, _src);
+
+ *( (uint32_t*)_dst) = 0
+ | (uint32_t(tmp[0]) )
+ | (uint32_t(tmp[1]) << 9)
+ | (uint32_t(tmp[2]) <<18)
+ | (uint32_t(tmp[3]) <<27)
+ ;
+ }
+
+ inline void unpackRgb9E5F(float* _dst, const void* _src)
+ {
+ uint32_t packed = *( (const uint32_t*)_src);
+
+ float tmp[4];
+ tmp[0] = float( ( (packed ) & 0x1ff) ) / 511.0f;
+ tmp[1] = float( ( (packed>> 9) & 0x1ff) ) / 511.0f;
+ tmp[2] = float( ( (packed>>18) & 0x1ff) ) / 511.0f;
+ tmp[3] = float( ( (packed>>27) & 0x1f) );
+
+ decodeRgbE<9, 5>(_dst, tmp);
+ }
+
+ // RGBA32I
+ inline void packRgba32I(void* _dst, const float* _src)
+ {
+ memcpy(_dst, _src, 16);
+ }
+
+ inline void unpackRgba32I(float* _dst, const void* _src)
+ {
+ memcpy(_dst, _src, 16);
+ }
+
+ // RGBA32U
+ inline void packRgba32U(void* _dst, const float* _src)
+ {
+ memcpy(_dst, _src, 16);
+ }
+
+ inline void unpackRgba32U(float* _dst, const void* _src)
+ {
+ memcpy(_dst, _src, 16);
+ }
+
+ // RGBA32F
+ inline void packRgba32F(void* _dst, const float* _src)
+ {
+ memcpy(_dst, _src, 16);
+ }
+
+ inline void unpackRgba32F(float* _dst, const void* _src)
+ {
+ memcpy(_dst, _src, 16);
+ }
+
+ // R5G6B5
+ inline void packR5G6B5(void* _dst, const float* _src)
+ {
+ *( (uint16_t*)_dst) = 0
+ | uint16_t(toUnorm(_src[0], 31.0f)<<11)
+ | uint16_t(toUnorm(_src[1], 63.0f)<< 5)
+ | uint16_t(toUnorm(_src[2], 31.0f) )
+ ;
+ }
+
+ inline void unpackR5G6B5(float* _dst, const void* _src)
+ {
+ uint16_t packed = *( (const uint16_t*)_src);
+ _dst[0] = float( ( (packed>>11) & 0x1f) ) / 31.0f;
+ _dst[1] = float( ( (packed>> 5) & 0x3f) ) / 63.0f;
+ _dst[2] = float( ( (packed ) & 0x1f) ) / 31.0f;
+ _dst[3] = 1.0f;
+ }
+
+ // RGBA4
+ inline void packRgba4(void* _dst, const float* _src)
+ {
+ *( (uint16_t*)_dst) = 0
+ | uint16_t(toUnorm(_src[0], 15.0f) )
+ | uint16_t(toUnorm(_src[1], 15.0f)<< 4)
+ | uint16_t(toUnorm(_src[2], 15.0f)<< 8)
+ | uint16_t(toUnorm(_src[3], 15.0f)<<12)
+ ;
+ }
+
+ inline void unpackRgba4(float* _dst, const void* _src)
+ {
+ uint16_t packed = *( (const uint16_t*)_src);
+ _dst[0] = float( ( (packed ) & 0xf) ) / 15.0f;
+ _dst[1] = float( ( (packed>> 4) & 0xf) ) / 15.0f;
+ _dst[2] = float( ( (packed>> 8) & 0xf) ) / 15.0f;
+ _dst[3] = float( ( (packed>>12) & 0xf) ) / 15.0f;
+ }
+
+ // RGBA4
+ inline void packBgra4(void* _dst, const float* _src)
+ {
+ *( (uint16_t*)_dst) = 0
+ | uint16_t(toUnorm(_src[0], 15.0f)<< 8)
+ | uint16_t(toUnorm(_src[1], 15.0f)<< 4)
+ | uint16_t(toUnorm(_src[2], 15.0f) )
+ | uint16_t(toUnorm(_src[3], 15.0f)<<12)
+ ;
+ }
+
+ inline void unpackBgra4(float* _dst, const void* _src)
+ {
+ uint16_t packed = *( (const uint16_t*)_src);
+ _dst[0] = float( ( (packed>> 8) & 0xf) ) / 15.0f;
+ _dst[1] = float( ( (packed>> 4) & 0xf) ) / 15.0f;
+ _dst[2] = float( ( (packed ) & 0xf) ) / 15.0f;
+ _dst[3] = float( ( (packed>>12) & 0xf) ) / 15.0f;
+ }
+
+ // RGB5A1
+ inline void packRgb5a1(void* _dst, const float* _src)
+ {
+ *( (uint16_t*)_dst) = 0
+ | uint16_t(toUnorm(_src[0], 31.0f) )
+ | uint16_t(toUnorm(_src[1], 31.0f)<< 5)
+ | uint16_t(toUnorm(_src[2], 31.0f)<<10)
+ | uint16_t(toUnorm(_src[3], 1.0f)<<15)
+ ;
+ }
+
+ inline void unpackRgb5a1(float* _dst, const void* _src)
+ {
+ uint16_t packed = *( (const uint16_t*)_src);
+ _dst[0] = float( ( (packed ) & 0x1f) ) / 31.0f;
+ _dst[1] = float( ( (packed>> 5) & 0x1f) ) / 31.0f;
+ _dst[2] = float( ( (packed>>10) & 0x1f) ) / 31.0f;
+ _dst[3] = float( ( (packed>>14) & 0x1) );
+ }
+
+ // BGR5A1
+ inline void packBgr5a1(void* _dst, const float* _src)
+ {
+ *( (uint16_t*)_dst) = 0
+ | uint16_t(toUnorm(_src[0], 31.0f)<<10)
+ | uint16_t(toUnorm(_src[1], 31.0f)<< 5)
+ | uint16_t(toUnorm(_src[2], 31.0f) )
+ | uint16_t(toUnorm(_src[3], 1.0f)<<15)
+ ;
+ }
+
+ inline void unpackBgr5a1(float* _dst, const void* _src)
+ {
+ uint16_t packed = *( (const uint16_t*)_src);
+ _dst[0] = float( ( (packed>>10) & 0x1f) ) / 31.0f;
+ _dst[1] = float( ( (packed>> 5) & 0x1f) ) / 31.0f;
+ _dst[2] = float( ( (packed ) & 0x1f) ) / 31.0f;
+ _dst[3] = float( ( (packed>>14) & 0x1) );
+ }
+
+ // RGB10A2
+ inline void packRgb10A2(void* _dst, const float* _src)
+ {
+ *( (uint32_t*)_dst) = 0
+ | (toUnorm(_src[0], 1023.0f) )
+ | (toUnorm(_src[1], 1023.0f)<<10)
+ | (toUnorm(_src[2], 1023.0f)<<20)
+ | (toUnorm(_src[3], 3.0f)<<30)
+ ;
+ }
+
+ inline void unpackRgb10A2(float* _dst, const void* _src)
+ {
+ uint32_t packed = *( (const uint32_t*)_src);
+ _dst[0] = float( ( (packed ) & 0x3ff) ) / 1023.0f;
+ _dst[1] = float( ( (packed>>10) & 0x3ff) ) / 1023.0f;
+ _dst[2] = float( ( (packed>>20) & 0x3ff) ) / 1023.0f;
+ _dst[3] = float( ( (packed>>30) & 0x3) ) / 3.0f;
+ }
+
+ // R11G11B10F
+ inline void packR11G11B10F(void* _dst, const float* _src)
+ {
+ *( (uint32_t*)_dst) = 0
+ | ( (halfFromFloat(_src[0])>> 4) & 0x7ff)
+ | ( (halfFromFloat(_src[0])<< 7) & 0x3ff800)
+ | ( (halfFromFloat(_src[0])<<17) & 0xffc00000)
+ ;
+ }
+
+ inline void unpackR11G11B10F(float* _dst, const void* _src)
+ {
+ uint32_t packed = *( (const uint32_t*)_src);
+ _dst[0] = halfToFloat( (packed<< 4) & 0x7ff0);
+ _dst[1] = halfToFloat( (packed>> 7) & 0x7ff0);
+ _dst[2] = halfToFloat( (packed>>17) & 0x7fe0);
+ _dst[3] = 1.0f;
+ }
+} // namespace bx
diff --git a/3rdparty/bx/include/bx/platform.h b/3rdparty/bx/include/bx/platform.h
index e976732c031..99d29a037d9 100644
--- a/3rdparty/bx/include/bx/platform.h
+++ b/3rdparty/bx/include/bx/platform.h
@@ -31,6 +31,7 @@
// C Runtime
#define BX_CRT_MSVC 0
#define BX_CRT_GLIBC 0
+#define BX_CRT_LIBCXX 0
#define BX_CRT_NEWLIB 0
#define BX_CRT_MINGW 0
#define BX_CRT_MUSL 0
@@ -68,7 +69,13 @@
# elif defined(__GLIBC__)
# undef BX_CRT_GLIBC
# define BX_CRT_GLIBC (__GLIBC__ * 10000 + __GLIBC_MINOR__ * 100)
-# endif // defined(__GLIBC__)
+# elif defined(__MINGW32__) || defined(__MINGW64__)
+# undef BX_CRT_MINGW
+# define BX_CRT_MINGW 1
+# elif defined(__apple_build_version__) || defined(__ANDROID__)
+# undef BX_CRT_LIBCXX
+# define BX_CRT_LIBCXX 1
+# endif //
#elif defined(_MSC_VER)
# undef BX_COMPILER_MSVC
# define BX_COMPILER_MSVC _MSC_VER
@@ -201,8 +208,7 @@
// RaspberryPi compiler defines __linux__
# undef BX_PLATFORM_RPI
# define BX_PLATFORM_RPI 1
-#elif defined(__linux__) \
- || BX_CPU_RISCV
+#elif defined(__linux__)
# undef BX_PLATFORM_LINUX
# define BX_PLATFORM_LINUX 1
#elif defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) \
@@ -231,24 +237,31 @@
#elif defined(__GNU__)
# undef BX_PLATFORM_HURD
# define BX_PLATFORM_HURD 1
-#else
-# error "BX_PLATFORM_* is not defined!"
#endif //
-#define BX_PLATFORM_POSIX (0 \
- || BX_PLATFORM_ANDROID \
- || BX_PLATFORM_EMSCRIPTEN \
- || BX_PLATFORM_BSD \
- || BX_PLATFORM_HURD \
- || BX_PLATFORM_IOS \
- || BX_PLATFORM_LINUX \
- || BX_PLATFORM_NACL \
- || BX_PLATFORM_OSX \
- || BX_PLATFORM_QNX \
- || BX_PLATFORM_STEAMLINK \
- || BX_PLATFORM_PS4 \
- || BX_PLATFORM_RPI \
- )
+#define BX_PLATFORM_POSIX (0 \
+ || BX_PLATFORM_ANDROID \
+ || BX_PLATFORM_EMSCRIPTEN \
+ || BX_PLATFORM_BSD \
+ || BX_PLATFORM_HURD \
+ || BX_PLATFORM_IOS \
+ || BX_PLATFORM_LINUX \
+ || BX_PLATFORM_NACL \
+ || BX_PLATFORM_OSX \
+ || BX_PLATFORM_QNX \
+ || BX_PLATFORM_STEAMLINK \
+ || BX_PLATFORM_PS4 \
+ || BX_PLATFORM_RPI \
+ )
+
+#define BX_CRT_NONE !(0 \
+ || BX_CRT_MSVC \
+ || BX_CRT_GLIBC \
+ || BX_CRT_LIBCXX \
+ || BX_CRT_NEWLIB \
+ || BX_CRT_MINGW \
+ || BX_CRT_MUSL \
+ )
#ifndef BX_CONFIG_ENABLE_MSVC_LEVEL4_WARNINGS
# define BX_CONFIG_ENABLE_MSVC_LEVEL4_WARNINGS 0
@@ -319,6 +332,8 @@
# define BX_PLATFORM_NAME "Xbox 360"
#elif BX_PLATFORM_XBOXONE
# define BX_PLATFORM_NAME "Xbox One"
+#else
+# define BX_PLATFORM_NAME "None"
#endif // BX_PLATFORM_
#if BX_CPU_ARM
@@ -335,6 +350,20 @@
# define BX_CPU_NAME "x86"
#endif // BX_CPU_
+#if BX_CRT_MSVC
+# define BX_CRT_NAME "MSVC C Runtime"
+#elif BX_CRT_GLIBC
+# define BX_CRT_NAME "GNU C Library"
+#elif BX_CRT_NEWLIB
+# define BX_CRT_NAME "Newlib"
+#elif BX_CRT_MINGW
+# define BX_CRT_NAME "MinGW C Runtime"
+#elif BX_CRT_MUSL
+# define BX_CRT_NAME "musl libc"
+#else
+# define BX_CRT_NAME "None"
+#endif // BX_CRT_
+
#if BX_ARCH_32BIT
# define BX_ARCH_NAME "32-bit"
#elif BX_ARCH_64BIT
diff --git a/3rdparty/bx/include/bx/process.h b/3rdparty/bx/include/bx/process.h
deleted file mode 100644
index 03c8f120624..00000000000
--- a/3rdparty/bx/include/bx/process.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright 2010-2017 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
- */
-
-#ifndef BX_PROCESS_H_HEADER_GUARD
-#define BX_PROCESS_H_HEADER_GUARD
-
-#include "string.h"
-#include "uint32_t.h"
-
-#if BX_PLATFORM_LINUX || BX_PLATFORM_HURD
-# include <unistd.h>
-#endif // BX_PLATFORM_LINUX || BX_PLATFORM_HURD
-
-namespace bx
-{
- ///
- inline void* exec(const char* const* _argv)
- {
-#if BX_PLATFORM_LINUX || BX_PLATFORM_HURD
- pid_t pid = fork();
-
- if (0 == pid)
- {
- int result = execvp(_argv[0], const_cast<char *const*>(&_argv[1]) );
- BX_UNUSED(result);
- return NULL;
- }
-
- return (void*)uintptr_t(pid);
-#elif BX_PLATFORM_WINDOWS
- STARTUPINFO si;
- memset(&si, 0, sizeof(STARTUPINFO) );
- si.cb = sizeof(STARTUPINFO);
-
- PROCESS_INFORMATION pi;
- memset(&pi, 0, sizeof(PROCESS_INFORMATION) );
-
- int32_t total = 0;
- for (uint32_t ii = 0; NULL != _argv[ii]; ++ii)
- {
- total += (int32_t)strlen(_argv[ii]) + 1;
- }
-
- char* temp = (char*)alloca(total);
- int32_t len = 0;
- for(uint32_t ii = 0; NULL != _argv[ii]; ++ii)
- {
- len += snprintf(&temp[len], bx::uint32_imax(0, total-len)
- , "%s "
- , _argv[ii]
- );
- }
-
- bool ok = CreateProcessA(_argv[0]
- , temp
- , NULL
- , NULL
- , false
- , 0
- , NULL
- , NULL
- , &si
- , &pi
- );
- if (ok)
- {
- return pi.hProcess;
- }
-
- return NULL;
-#else
- return NULL;
-#endif // BX_PLATFORM_LINUX || BX_PLATFORM_HURD
- }
-
-} // namespace bx
-
-#endif // BX_PROCESS_H_HEADER_GUARD
diff --git a/3rdparty/bx/include/bx/radixsort.h b/3rdparty/bx/include/bx/radixsort.h
index 2c4dd6a2408..87bd3e310b0 100644
--- a/3rdparty/bx/include/bx/radixsort.h
+++ b/3rdparty/bx/include/bx/radixsort.h
@@ -10,282 +10,42 @@
namespace bx
{
-#define BX_RADIXSORT_BITS 11
-#define BX_RADIXSORT_HISTOGRAM_SIZE (1<<BX_RADIXSORT_BITS)
-#define BX_RADIXSORT_BIT_MASK (BX_RADIXSORT_HISTOGRAM_SIZE-1)
-
- inline void radixSort(uint32_t* __restrict _keys, uint32_t* __restrict _tempKeys, uint32_t _size)
- {
- uint32_t* __restrict keys = _keys;
- uint32_t* __restrict tempKeys = _tempKeys;
-
- uint32_t histogram[BX_RADIXSORT_HISTOGRAM_SIZE];
- uint16_t shift = 0;
- uint32_t pass = 0;
- for (; pass < 3; ++pass)
- {
- memset(histogram, 0, sizeof(uint32_t)*BX_RADIXSORT_HISTOGRAM_SIZE);
-
- bool sorted = true;
- {
- uint32_t key = keys[0];
- uint32_t prevKey = key;
- for (uint32_t ii = 0; ii < _size; ++ii, prevKey = key)
- {
- key = keys[ii];
- uint16_t index = (key>>shift)&BX_RADIXSORT_BIT_MASK;
- ++histogram[index];
- sorted &= prevKey <= key;
- }
- }
-
- if (sorted)
- {
- goto done;
- }
-
- uint32_t offset = 0;
- for (uint32_t ii = 0; ii < BX_RADIXSORT_HISTOGRAM_SIZE; ++ii)
- {
- uint32_t count = histogram[ii];
- histogram[ii] = offset;
- offset += count;
- }
-
- for (uint32_t ii = 0; ii < _size; ++ii)
- {
- uint32_t key = keys[ii];
- uint16_t index = (key>>shift)&BX_RADIXSORT_BIT_MASK;
- uint32_t dest = histogram[index]++;
- tempKeys[dest] = key;
- }
-
- uint32_t* swapKeys = tempKeys;
- tempKeys = keys;
- keys = swapKeys;
-
- shift += BX_RADIXSORT_BITS;
- }
-
-done:
- if (0 != (pass&1) )
- {
- // Odd number of passes needs to do copy to the destination.
- memcpy(_keys, _tempKeys, _size*sizeof(uint32_t) );
- }
- }
-
+ ///
+ void radixSort(
+ uint32_t* __restrict _keys
+ , uint32_t* __restrict _tempKeys
+ , uint32_t _size
+ );
+
+ ///
template <typename Ty>
- inline void radixSort(uint32_t* __restrict _keys, uint32_t* __restrict _tempKeys, Ty* __restrict _values, Ty* __restrict _tempValues, uint32_t _size)
- {
- uint32_t* __restrict keys = _keys;
- uint32_t* __restrict tempKeys = _tempKeys;
- Ty* __restrict values = _values;
- Ty* __restrict tempValues = _tempValues;
-
- uint32_t histogram[BX_RADIXSORT_HISTOGRAM_SIZE];
- uint16_t shift = 0;
- uint32_t pass = 0;
- for (; pass < 3; ++pass)
- {
- memset(histogram, 0, sizeof(uint32_t)*BX_RADIXSORT_HISTOGRAM_SIZE);
-
- bool sorted = true;
- {
- uint32_t key = keys[0];
- uint32_t prevKey = key;
- for (uint32_t ii = 0; ii < _size; ++ii, prevKey = key)
- {
- key = keys[ii];
- uint16_t index = (key>>shift)&BX_RADIXSORT_BIT_MASK;
- ++histogram[index];
- sorted &= prevKey <= key;
- }
- }
-
- if (sorted)
- {
- goto done;
- }
-
- uint32_t offset = 0;
- for (uint32_t ii = 0; ii < BX_RADIXSORT_HISTOGRAM_SIZE; ++ii)
- {
- uint32_t count = histogram[ii];
- histogram[ii] = offset;
- offset += count;
- }
-
- for (uint32_t ii = 0; ii < _size; ++ii)
- {
- uint32_t key = keys[ii];
- uint16_t index = (key>>shift)&BX_RADIXSORT_BIT_MASK;
- uint32_t dest = histogram[index]++;
- tempKeys[dest] = key;
- tempValues[dest] = values[ii];
- }
-
- uint32_t* swapKeys = tempKeys;
- tempKeys = keys;
- keys = swapKeys;
-
- Ty* swapValues = tempValues;
- tempValues = values;
- values = swapValues;
-
- shift += BX_RADIXSORT_BITS;
- }
-
-done:
- if (0 != (pass&1) )
- {
- // Odd number of passes needs to do copy to the destination.
- memcpy(_keys, _tempKeys, _size*sizeof(uint32_t) );
- for (uint32_t ii = 0; ii < _size; ++ii)
- {
- _values[ii] = _tempValues[ii];
- }
- }
- }
-
- inline void radixSort(uint64_t* __restrict _keys, uint64_t* __restrict _tempKeys, uint32_t _size)
- {
- uint64_t* __restrict keys = _keys;
- uint64_t* __restrict tempKeys = _tempKeys;
-
- uint32_t histogram[BX_RADIXSORT_HISTOGRAM_SIZE];
- uint16_t shift = 0;
- uint32_t pass = 0;
- for (; pass < 6; ++pass)
- {
- memset(histogram, 0, sizeof(uint32_t)*BX_RADIXSORT_HISTOGRAM_SIZE);
-
- bool sorted = true;
- {
- uint64_t key = keys[0];
- uint64_t prevKey = key;
- for (uint32_t ii = 0; ii < _size; ++ii, prevKey = key)
- {
- key = keys[ii];
- uint16_t index = (key>>shift)&BX_RADIXSORT_BIT_MASK;
- ++histogram[index];
- sorted &= prevKey <= key;
- }
- }
-
- if (sorted)
- {
- goto done;
- }
-
- uint32_t offset = 0;
- for (uint32_t ii = 0; ii < BX_RADIXSORT_HISTOGRAM_SIZE; ++ii)
- {
- uint32_t count = histogram[ii];
- histogram[ii] = offset;
- offset += count;
- }
-
- for (uint32_t ii = 0; ii < _size; ++ii)
- {
- uint64_t key = keys[ii];
- uint16_t index = (key>>shift)&BX_RADIXSORT_BIT_MASK;
- uint32_t dest = histogram[index]++;
- tempKeys[dest] = key;
- }
-
- uint64_t* swapKeys = tempKeys;
- tempKeys = keys;
- keys = swapKeys;
-
- shift += BX_RADIXSORT_BITS;
- }
-
-done:
- if (0 != (pass&1) )
- {
- // Odd number of passes needs to do copy to the destination.
- memcpy(_keys, _tempKeys, _size*sizeof(uint64_t) );
- }
- }
-
+ void radixSort(
+ uint32_t* __restrict _keys
+ , uint32_t* __restrict _tempKeys
+ , Ty* __restrict _values
+ , Ty* __restrict _tempValues
+ , uint32_t _size
+ );
+
+ ///
+ void radixSort(
+ uint64_t* __restrict _keys
+ , uint64_t* __restrict _tempKeys
+ , uint32_t _size
+ );
+
+ ///
template <typename Ty>
- inline void radixSort(uint64_t* __restrict _keys, uint64_t* __restrict _tempKeys, Ty* __restrict _values, Ty* __restrict _tempValues, uint32_t _size)
- {
- uint64_t* __restrict keys = _keys;
- uint64_t* __restrict tempKeys = _tempKeys;
- Ty* __restrict values = _values;
- Ty* __restrict tempValues = _tempValues;
-
- uint32_t histogram[BX_RADIXSORT_HISTOGRAM_SIZE];
- uint16_t shift = 0;
- uint32_t pass = 0;
- for (; pass < 6; ++pass)
- {
- memset(histogram, 0, sizeof(uint32_t)*BX_RADIXSORT_HISTOGRAM_SIZE);
-
- bool sorted = true;
- {
- uint64_t key = keys[0];
- uint64_t prevKey = key;
- for (uint32_t ii = 0; ii < _size; ++ii, prevKey = key)
- {
- key = keys[ii];
- uint16_t index = (key>>shift)&BX_RADIXSORT_BIT_MASK;
- ++histogram[index];
- sorted &= prevKey <= key;
- }
- }
-
- if (sorted)
- {
- goto done;
- }
-
- uint32_t offset = 0;
- for (uint32_t ii = 0; ii < BX_RADIXSORT_HISTOGRAM_SIZE; ++ii)
- {
- uint32_t count = histogram[ii];
- histogram[ii] = offset;
- offset += count;
- }
-
- for (uint32_t ii = 0; ii < _size; ++ii)
- {
- uint64_t key = keys[ii];
- uint16_t index = (key>>shift)&BX_RADIXSORT_BIT_MASK;
- uint32_t dest = histogram[index]++;
- tempKeys[dest] = key;
- tempValues[dest] = values[ii];
- }
-
- uint64_t* swapKeys = tempKeys;
- tempKeys = keys;
- keys = swapKeys;
-
- Ty* swapValues = tempValues;
- tempValues = values;
- values = swapValues;
-
- shift += BX_RADIXSORT_BITS;
- }
-
-done:
- if (0 != (pass&1) )
- {
- // Odd number of passes needs to do copy to the destination.
- memcpy(_keys, _tempKeys, _size*sizeof(uint64_t) );
- for (uint32_t ii = 0; ii < _size; ++ii)
- {
- _values[ii] = _tempValues[ii];
- }
- }
- }
-
-#undef BX_RADIXSORT_BITS
-#undef BX_RADIXSORT_HISTOGRAM_SIZE
-#undef BX_RADIXSORT_BIT_MASK
+ void radixSort(
+ uint64_t* __restrict _keys
+ , uint64_t* __restrict _tempKeys
+ , Ty* __restrict _values
+ , Ty* __restrict _tempValues
+ , uint32_t _size
+ );
} // namespace bx
+#include "radixsort.inl"
+
#endif // BX_RADIXSORT_H_HEADER_GUARD
diff --git a/3rdparty/bx/include/bx/radixsort.inl b/3rdparty/bx/include/bx/radixsort.inl
new file mode 100644
index 00000000000..2edc5e40fd3
--- /dev/null
+++ b/3rdparty/bx/include/bx/radixsort.inl
@@ -0,0 +1,288 @@
+/*
+ * Copyright 2010-2017 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ */
+
+#ifndef BX_RADIXSORT_H_HEADER_GUARD
+# error "Must be included from bx/radixsort.h!"
+#endif // BX_RADIXSORT_H_HEADER_GUARD
+
+namespace bx
+{
+#define BX_RADIXSORT_BITS 11
+#define BX_RADIXSORT_HISTOGRAM_SIZE (1<<BX_RADIXSORT_BITS)
+#define BX_RADIXSORT_BIT_MASK (BX_RADIXSORT_HISTOGRAM_SIZE-1)
+
+ inline void radixSort(uint32_t* __restrict _keys, uint32_t* __restrict _tempKeys, uint32_t _size)
+ {
+ uint32_t* __restrict keys = _keys;
+ uint32_t* __restrict tempKeys = _tempKeys;
+
+ uint32_t histogram[BX_RADIXSORT_HISTOGRAM_SIZE];
+ uint16_t shift = 0;
+ uint32_t pass = 0;
+ for (; pass < 3; ++pass)
+ {
+ memset(histogram, 0, sizeof(uint32_t)*BX_RADIXSORT_HISTOGRAM_SIZE);
+
+ bool sorted = true;
+ {
+ uint32_t key = keys[0];
+ uint32_t prevKey = key;
+ for (uint32_t ii = 0; ii < _size; ++ii, prevKey = key)
+ {
+ key = keys[ii];
+ uint16_t index = (key>>shift)&BX_RADIXSORT_BIT_MASK;
+ ++histogram[index];
+ sorted &= prevKey <= key;
+ }
+ }
+
+ if (sorted)
+ {
+ goto done;
+ }
+
+ uint32_t offset = 0;
+ for (uint32_t ii = 0; ii < BX_RADIXSORT_HISTOGRAM_SIZE; ++ii)
+ {
+ uint32_t count = histogram[ii];
+ histogram[ii] = offset;
+ offset += count;
+ }
+
+ for (uint32_t ii = 0; ii < _size; ++ii)
+ {
+ uint32_t key = keys[ii];
+ uint16_t index = (key>>shift)&BX_RADIXSORT_BIT_MASK;
+ uint32_t dest = histogram[index]++;
+ tempKeys[dest] = key;
+ }
+
+ uint32_t* swapKeys = tempKeys;
+ tempKeys = keys;
+ keys = swapKeys;
+
+ shift += BX_RADIXSORT_BITS;
+ }
+
+done:
+ if (0 != (pass&1) )
+ {
+ // Odd number of passes needs to do copy to the destination.
+ memcpy(_keys, _tempKeys, _size*sizeof(uint32_t) );
+ }
+ }
+
+ template <typename Ty>
+ inline void radixSort(uint32_t* __restrict _keys, uint32_t* __restrict _tempKeys, Ty* __restrict _values, Ty* __restrict _tempValues, uint32_t _size)
+ {
+ uint32_t* __restrict keys = _keys;
+ uint32_t* __restrict tempKeys = _tempKeys;
+ Ty* __restrict values = _values;
+ Ty* __restrict tempValues = _tempValues;
+
+ uint32_t histogram[BX_RADIXSORT_HISTOGRAM_SIZE];
+ uint16_t shift = 0;
+ uint32_t pass = 0;
+ for (; pass < 3; ++pass)
+ {
+ memset(histogram, 0, sizeof(uint32_t)*BX_RADIXSORT_HISTOGRAM_SIZE);
+
+ bool sorted = true;
+ {
+ uint32_t key = keys[0];
+ uint32_t prevKey = key;
+ for (uint32_t ii = 0; ii < _size; ++ii, prevKey = key)
+ {
+ key = keys[ii];
+ uint16_t index = (key>>shift)&BX_RADIXSORT_BIT_MASK;
+ ++histogram[index];
+ sorted &= prevKey <= key;
+ }
+ }
+
+ if (sorted)
+ {
+ goto done;
+ }
+
+ uint32_t offset = 0;
+ for (uint32_t ii = 0; ii < BX_RADIXSORT_HISTOGRAM_SIZE; ++ii)
+ {
+ uint32_t count = histogram[ii];
+ histogram[ii] = offset;
+ offset += count;
+ }
+
+ for (uint32_t ii = 0; ii < _size; ++ii)
+ {
+ uint32_t key = keys[ii];
+ uint16_t index = (key>>shift)&BX_RADIXSORT_BIT_MASK;
+ uint32_t dest = histogram[index]++;
+ tempKeys[dest] = key;
+ tempValues[dest] = values[ii];
+ }
+
+ uint32_t* swapKeys = tempKeys;
+ tempKeys = keys;
+ keys = swapKeys;
+
+ Ty* swapValues = tempValues;
+ tempValues = values;
+ values = swapValues;
+
+ shift += BX_RADIXSORT_BITS;
+ }
+
+done:
+ if (0 != (pass&1) )
+ {
+ // Odd number of passes needs to do copy to the destination.
+ memcpy(_keys, _tempKeys, _size*sizeof(uint32_t) );
+ for (uint32_t ii = 0; ii < _size; ++ii)
+ {
+ _values[ii] = _tempValues[ii];
+ }
+ }
+ }
+
+ inline void radixSort(uint64_t* __restrict _keys, uint64_t* __restrict _tempKeys, uint32_t _size)
+ {
+ uint64_t* __restrict keys = _keys;
+ uint64_t* __restrict tempKeys = _tempKeys;
+
+ uint32_t histogram[BX_RADIXSORT_HISTOGRAM_SIZE];
+ uint16_t shift = 0;
+ uint32_t pass = 0;
+ for (; pass < 6; ++pass)
+ {
+ memset(histogram, 0, sizeof(uint32_t)*BX_RADIXSORT_HISTOGRAM_SIZE);
+
+ bool sorted = true;
+ {
+ uint64_t key = keys[0];
+ uint64_t prevKey = key;
+ for (uint32_t ii = 0; ii < _size; ++ii, prevKey = key)
+ {
+ key = keys[ii];
+ uint16_t index = (key>>shift)&BX_RADIXSORT_BIT_MASK;
+ ++histogram[index];
+ sorted &= prevKey <= key;
+ }
+ }
+
+ if (sorted)
+ {
+ goto done;
+ }
+
+ uint32_t offset = 0;
+ for (uint32_t ii = 0; ii < BX_RADIXSORT_HISTOGRAM_SIZE; ++ii)
+ {
+ uint32_t count = histogram[ii];
+ histogram[ii] = offset;
+ offset += count;
+ }
+
+ for (uint32_t ii = 0; ii < _size; ++ii)
+ {
+ uint64_t key = keys[ii];
+ uint16_t index = (key>>shift)&BX_RADIXSORT_BIT_MASK;
+ uint32_t dest = histogram[index]++;
+ tempKeys[dest] = key;
+ }
+
+ uint64_t* swapKeys = tempKeys;
+ tempKeys = keys;
+ keys = swapKeys;
+
+ shift += BX_RADIXSORT_BITS;
+ }
+
+done:
+ if (0 != (pass&1) )
+ {
+ // Odd number of passes needs to do copy to the destination.
+ memcpy(_keys, _tempKeys, _size*sizeof(uint64_t) );
+ }
+ }
+
+ template <typename Ty>
+ inline void radixSort(uint64_t* __restrict _keys, uint64_t* __restrict _tempKeys, Ty* __restrict _values, Ty* __restrict _tempValues, uint32_t _size)
+ {
+ uint64_t* __restrict keys = _keys;
+ uint64_t* __restrict tempKeys = _tempKeys;
+ Ty* __restrict values = _values;
+ Ty* __restrict tempValues = _tempValues;
+
+ uint32_t histogram[BX_RADIXSORT_HISTOGRAM_SIZE];
+ uint16_t shift = 0;
+ uint32_t pass = 0;
+ for (; pass < 6; ++pass)
+ {
+ memset(histogram, 0, sizeof(uint32_t)*BX_RADIXSORT_HISTOGRAM_SIZE);
+
+ bool sorted = true;
+ {
+ uint64_t key = keys[0];
+ uint64_t prevKey = key;
+ for (uint32_t ii = 0; ii < _size; ++ii, prevKey = key)
+ {
+ key = keys[ii];
+ uint16_t index = (key>>shift)&BX_RADIXSORT_BIT_MASK;
+ ++histogram[index];
+ sorted &= prevKey <= key;
+ }
+ }
+
+ if (sorted)
+ {
+ goto done;
+ }
+
+ uint32_t offset = 0;
+ for (uint32_t ii = 0; ii < BX_RADIXSORT_HISTOGRAM_SIZE; ++ii)
+ {
+ uint32_t count = histogram[ii];
+ histogram[ii] = offset;
+ offset += count;
+ }
+
+ for (uint32_t ii = 0; ii < _size; ++ii)
+ {
+ uint64_t key = keys[ii];
+ uint16_t index = (key>>shift)&BX_RADIXSORT_BIT_MASK;
+ uint32_t dest = histogram[index]++;
+ tempKeys[dest] = key;
+ tempValues[dest] = values[ii];
+ }
+
+ uint64_t* swapKeys = tempKeys;
+ tempKeys = keys;
+ keys = swapKeys;
+
+ Ty* swapValues = tempValues;
+ tempValues = values;
+ values = swapValues;
+
+ shift += BX_RADIXSORT_BITS;
+ }
+
+done:
+ if (0 != (pass&1) )
+ {
+ // Odd number of passes needs to do copy to the destination.
+ memcpy(_keys, _tempKeys, _size*sizeof(uint64_t) );
+ for (uint32_t ii = 0; ii < _size; ++ii)
+ {
+ _values[ii] = _tempValues[ii];
+ }
+ }
+ }
+
+#undef BX_RADIXSORT_BITS
+#undef BX_RADIXSORT_HISTOGRAM_SIZE
+#undef BX_RADIXSORT_BIT_MASK
+
+} // namespace bx
diff --git a/3rdparty/bx/include/bx/readerwriter.h b/3rdparty/bx/include/bx/readerwriter.h
index d926628430d..19411a6adb7 100644
--- a/3rdparty/bx/include/bx/readerwriter.h
+++ b/3rdparty/bx/include/bx/readerwriter.h
@@ -24,6 +24,7 @@ BX_ERROR_RESULT(BX_ERROR_READERWRITER_ALREADY_OPEN, BX_MAKEFOURCC('R', 'W', 0, 5
namespace bx
{
+ ///
struct Whence
{
enum Enum
@@ -34,350 +35,111 @@ namespace bx
};
};
+ ///
struct BX_NO_VTABLE ReaderI
{
virtual ~ReaderI() = 0;
virtual int32_t read(void* _data, int32_t _size, Error* _err) = 0;
};
- inline ReaderI::~ReaderI()
- {
- }
-
+ ///
struct BX_NO_VTABLE WriterI
{
virtual ~WriterI() = 0;
virtual int32_t write(const void* _data, int32_t _size, Error* _err) = 0;
};
- inline WriterI::~WriterI()
- {
- }
-
+ ///
struct BX_NO_VTABLE SeekerI
{
virtual ~SeekerI() = 0;
virtual int64_t seek(int64_t _offset = 0, Whence::Enum _whence = Whence::Current) = 0;
};
- inline SeekerI::~SeekerI()
- {
- }
-
- /// Read data.
- inline int32_t read(ReaderI* _reader, void* _data, int32_t _size, Error* _err = NULL)
- {
- BX_ERROR_SCOPE(_err);
- return _reader->read(_data, _size, _err);
- }
-
- /// Read value.
- template<typename Ty>
- inline int32_t read(ReaderI* _reader, Ty& _value, Error* _err = NULL)
- {
- BX_ERROR_SCOPE(_err);
- BX_STATIC_ASSERT(BX_TYPE_IS_POD(Ty) );
- return _reader->read(&_value, sizeof(Ty), _err);
- }
-
- /// Read value and converts it to host endianess. _fromLittleEndian specifies
- /// underlying stream endianess.
- template<typename Ty>
- inline int32_t readHE(ReaderI* _reader, Ty& _value, bool _fromLittleEndian, Error* _err = NULL)
- {
- BX_ERROR_SCOPE(_err);
- BX_STATIC_ASSERT(BX_TYPE_IS_POD(Ty) );
- Ty value;
- int32_t result = _reader->read(&value, sizeof(Ty), _err);
- _value = toHostEndian(value, _fromLittleEndian);
- return result;
- }
-
- /// Write data.
- inline int32_t write(WriterI* _writer, const void* _data, int32_t _size, Error* _err = NULL)
- {
- BX_ERROR_SCOPE(_err);
- return _writer->write(_data, _size, _err);
- }
-
- /// Write repeat the same value.
- inline int32_t writeRep(WriterI* _writer, uint8_t _byte, int32_t _size, Error* _err = NULL)
- {
- BX_ERROR_SCOPE(_err);
-
- const uint32_t tmp0 = uint32_sels(64 - _size, 64, _size);
- const uint32_t tmp1 = uint32_sels(256 - _size, 256, tmp0);
- const uint32_t blockSize = uint32_sels(1024 - _size, 1024, tmp1);
- uint8_t* temp = (uint8_t*)alloca(blockSize);
- memset(temp, _byte, blockSize);
-
- int32_t size = 0;
- while (0 < _size)
- {
- int32_t bytes = write(_writer, temp, uint32_min(blockSize, _size), _err);
- size += bytes;
- _size -= bytes;
- }
-
- return size;
- }
-
- /// Write value.
- template<typename Ty>
- inline int32_t write(WriterI* _writer, const Ty& _value, Error* _err = NULL)
- {
- BX_ERROR_SCOPE(_err);
- BX_STATIC_ASSERT(BX_TYPE_IS_POD(Ty) );
- return _writer->write(&_value, sizeof(Ty), _err);
- }
-
- /// Write value as little endian.
- template<typename Ty>
- inline int32_t writeLE(WriterI* _writer, const Ty& _value, Error* _err = NULL)
- {
- BX_ERROR_SCOPE(_err);
- BX_STATIC_ASSERT(BX_TYPE_IS_POD(Ty) );
- Ty value = toLittleEndian(_value);
- int32_t result = _writer->write(&value, sizeof(Ty), _err);
- return result;
- }
-
- /// Write value as big endian.
- template<typename Ty>
- inline int32_t writeBE(WriterI* _writer, const Ty& _value, Error* _err = NULL)
- {
- BX_ERROR_SCOPE(_err);
- BX_STATIC_ASSERT(BX_TYPE_IS_POD(Ty) );
- Ty value = toBigEndian(_value);
- int32_t result = _writer->write(&value, sizeof(Ty), _err);
- return result;
- }
-
- /// Write formated string.
- inline int32_t writePrintf(WriterI* _writer, const char* _format, ...)
- {
- va_list argList;
- va_start(argList, _format);
-
- char temp[2048];
- char* out = temp;
- int32_t max = sizeof(temp);
- int32_t len = vsnprintf(out, max, _format, argList);
- if (len > max)
- {
- out = (char*)alloca(len);
- len = vsnprintf(out, len, _format, argList);
- }
-
- int32_t size = write(_writer, out, len);
-
- va_end(argList);
-
- return size;
- }
-
- /// Skip _offset bytes forward.
- inline int64_t skip(SeekerI* _seeker, int64_t _offset)
- {
- return _seeker->seek(_offset, Whence::Current);
- }
-
- /// Seek to any position in file.
- inline int64_t seek(SeekerI* _seeker, int64_t _offset = 0, Whence::Enum _whence = Whence::Current)
- {
- return _seeker->seek(_offset, _whence);
- }
-
- /// Returns size of file.
- inline int64_t getSize(SeekerI* _seeker)
- {
- int64_t offset = _seeker->seek();
- int64_t size = _seeker->seek(0, Whence::End);
- _seeker->seek(offset, Whence::Begin);
- return size;
- }
-
+ ///
struct BX_NO_VTABLE ReaderSeekerI : public ReaderI, public SeekerI
{
};
- /// Peek data.
- inline int32_t peek(ReaderSeekerI* _reader, void* _data, int32_t _size, Error* _err = NULL)
- {
- BX_ERROR_SCOPE(_err);
- int64_t offset = bx::seek(_reader);
- int32_t size = _reader->read(_data, _size, _err);
- bx::seek(_reader, offset, bx::Whence::Begin);
- return size;
- }
-
- /// Peek value.
- template<typename Ty>
- inline int32_t peek(ReaderSeekerI* _reader, Ty& _value, Error* _err = NULL)
- {
- BX_ERROR_SCOPE(_err);
- BX_STATIC_ASSERT(BX_TYPE_IS_POD(Ty) );
- return peek(_reader, &_value, sizeof(Ty), _err);
- }
-
+ ///
struct BX_NO_VTABLE WriterSeekerI : public WriterI, public SeekerI
{
};
- /// Align reader stream.
- inline int32_t align(ReaderSeekerI* _reader, uint32_t _alignment, Error* _err = NULL)
- {
- BX_ERROR_SCOPE(_err);
- const int64_t current = bx::seek(_reader);
- const int64_t aligned = ( (current + _alignment-1)/_alignment) * _alignment;
- const int32_t size = int32_t(aligned - current);
- if (0 != size)
- {
- const int64_t offset = bx::seek(_reader, size);
- if (offset != aligned)
- {
- BX_ERROR_SET(_err, BX_ERROR_READERWRITER_WRITE, "Align: read truncated.");
- }
- return int32_t(offset - current);
- }
-
- return 0;
- }
-
- /// Align writer stream (pads stream with zeros).
- inline int32_t align(WriterSeekerI* _writer, uint32_t _alignment, Error* _err = NULL)
- {
- BX_ERROR_SCOPE(_err);
- const int64_t current = bx::seek(_writer);
- const int64_t aligned = ( (current + _alignment-1)/_alignment) * _alignment;
- const int32_t size = int32_t(aligned - current);
- if (0 != size)
- {
- return writeRep(_writer, 0, size, _err);
- }
-
- return 0;
- }
-
+ ///
struct BX_NO_VTABLE ReaderOpenI
{
virtual ~ReaderOpenI() = 0;
virtual bool open(const char* _filePath, Error* _err) = 0;
};
- inline ReaderOpenI::~ReaderOpenI()
- {
- }
-
+ ///
struct BX_NO_VTABLE WriterOpenI
{
virtual ~WriterOpenI() = 0;
virtual bool open(const char* _filePath, bool _append, Error* _err) = 0;
};
- inline WriterOpenI::~WriterOpenI()
- {
- }
-
+ ///
struct BX_NO_VTABLE CloserI
{
virtual ~CloserI() = 0;
virtual void close() = 0;
};
- inline CloserI::~CloserI()
- {
- }
-
+ ///
struct BX_NO_VTABLE FileReaderI : public ReaderOpenI, public CloserI, public ReaderSeekerI
{
};
+ ///
struct BX_NO_VTABLE FileWriterI : public WriterOpenI, public CloserI, public WriterSeekerI
{
};
- inline bool open(ReaderOpenI* _reader, const char* _filePath, Error* _err = NULL)
- {
- BX_ERROR_USE_TEMP_WHEN_NULL(_err);
- return _reader->open(_filePath, _err);
- }
-
- inline bool open(WriterOpenI* _writer, const char* _filePath, bool _append = false, Error* _err = NULL)
- {
- BX_ERROR_USE_TEMP_WHEN_NULL(_err);
- return _writer->open(_filePath, _append, _err);
- }
-
- inline void close(CloserI* _reader)
- {
- _reader->close();
- }
-
+ ///
struct BX_NO_VTABLE MemoryBlockI
{
virtual void* more(uint32_t _size = 0) = 0;
virtual uint32_t getSize() = 0;
};
+ ///
class StaticMemoryBlock : public MemoryBlockI
{
public:
- StaticMemoryBlock(void* _data, uint32_t _size)
- : m_data(_data)
- , m_size(_size)
- {
- }
+ ///
+ StaticMemoryBlock(void* _data, uint32_t _size);
- virtual ~StaticMemoryBlock()
- {
- }
+ ///
+ virtual ~StaticMemoryBlock();
- virtual void* more(uint32_t /*_size*/ = 0) BX_OVERRIDE
- {
- return m_data;
- }
+ ///
+ virtual void* more(uint32_t _size = 0);
- virtual uint32_t getSize() BX_OVERRIDE
- {
- return m_size;
- }
+ ///
+ virtual uint32_t getSize() BX_OVERRIDE;
private:
void* m_data;
uint32_t m_size;
};
+ ///
class MemoryBlock : public MemoryBlockI
{
public:
- MemoryBlock(AllocatorI* _allocator)
- : m_allocator(_allocator)
- , m_data(NULL)
- , m_size(0)
- {
- }
+ ///
+ MemoryBlock(AllocatorI* _allocator);
- virtual ~MemoryBlock()
- {
- BX_FREE(m_allocator, m_data);
- }
+ ///
+ virtual ~MemoryBlock();
- virtual void* more(uint32_t _size = 0) BX_OVERRIDE
- {
- if (0 < _size)
- {
- m_size += _size;
- m_data = BX_REALLOC(m_allocator, m_data, m_size);
- }
+ ///
+ virtual void* more(uint32_t _size = 0) BX_OVERRIDE;
- return m_data;
- }
-
- virtual uint32_t getSize() BX_OVERRIDE
- {
- return m_size;
- }
+ ///
+ virtual uint32_t getSize() BX_OVERRIDE;
private:
AllocatorI* m_allocator;
@@ -385,128 +147,51 @@ namespace bx
uint32_t m_size;
};
+ ///
class SizerWriter : public WriterSeekerI
{
public:
- SizerWriter()
- : m_pos(0)
- , m_top(0)
- {
- }
-
- virtual ~SizerWriter()
- {
- }
-
- virtual int64_t seek(int64_t _offset = 0, Whence::Enum _whence = Whence::Current) BX_OVERRIDE
- {
- switch (_whence)
- {
- case Whence::Begin:
- m_pos = int64_clamp(_offset, 0, m_top);
- break;
-
- case Whence::Current:
- m_pos = int64_clamp(m_pos + _offset, 0, m_top);
- break;
-
- case Whence::End:
- m_pos = int64_clamp(m_top - _offset, 0, m_top);
- break;
- }
-
- return m_pos;
- }
-
- virtual int32_t write(const void* /*_data*/, int32_t _size, Error* _err) BX_OVERRIDE
- {
- BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
+ ///
+ SizerWriter();
- int32_t morecore = int32_t(m_pos - m_top) + _size;
+ ///
+ virtual ~SizerWriter();
- if (0 < morecore)
- {
- m_top += morecore;
- }
+ ///
+ virtual int64_t seek(int64_t _offset = 0, Whence::Enum _whence = Whence::Current) BX_OVERRIDE;
- int64_t remainder = m_top-m_pos;
- int32_t size = uint32_min(_size, uint32_t(int64_min(remainder, INT32_MAX) ) );
- m_pos += size;
- if (size != _size)
- {
- BX_ERROR_SET(_err, BX_ERROR_READERWRITER_WRITE, "SizerWriter: write truncated.");
- }
- return size;
- }
+ ///
+ virtual int32_t write(const void* /*_data*/, int32_t _size, Error* _err) BX_OVERRIDE;
private:
int64_t m_pos;
int64_t m_top;
};
+ ///
class MemoryReader : public ReaderSeekerI
{
public:
- MemoryReader(const void* _data, uint32_t _size)
- : m_data( (const uint8_t*)_data)
- , m_pos(0)
- , m_top(_size)
- {
- }
-
- virtual ~MemoryReader()
- {
- }
-
- virtual int64_t seek(int64_t _offset, Whence::Enum _whence) BX_OVERRIDE
- {
- switch (_whence)
- {
- case Whence::Begin:
- m_pos = int64_clamp(_offset, 0, m_top);
- break;
+ ///
+ MemoryReader(const void* _data, uint32_t _size);
- case Whence::Current:
- m_pos = int64_clamp(m_pos + _offset, 0, m_top);
- break;
+ ///
+ virtual ~MemoryReader();
- case Whence::End:
- m_pos = int64_clamp(m_top - _offset, 0, m_top);
- break;
- }
+ ///
+ virtual int64_t seek(int64_t _offset, Whence::Enum _whence) BX_OVERRIDE;
- return m_pos;
- }
+ ///
+ virtual int32_t read(void* _data, int32_t _size, Error* _err) BX_OVERRIDE;
- virtual int32_t read(void* _data, int32_t _size, Error* _err) BX_OVERRIDE
- {
- BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
-
- int64_t remainder = m_top-m_pos;
- int32_t size = uint32_min(_size, uint32_t(int64_min(remainder, INT32_MAX) ) );
- memcpy(_data, &m_data[m_pos], size);
- m_pos += size;
- if (size != _size)
- {
- BX_ERROR_SET(_err, BX_ERROR_READERWRITER_READ, "MemoryReader: read truncated.");
- }
- return size;
- }
-
- const uint8_t* getDataPtr() const
- {
- return &m_data[m_pos];
- }
+ ///
+ const uint8_t* getDataPtr() const;
- int64_t getPos() const
- {
- return m_pos;
- }
+ ///
+ int64_t getPos() const;
- int64_t remaining() const
- {
- return m_top-m_pos;
- }
+ ///
+ int64_t remaining() const;
private:
const uint8_t* m_data;
@@ -514,66 +199,21 @@ namespace bx
int64_t m_top;
};
+ ///
class MemoryWriter : public WriterSeekerI
{
public:
- MemoryWriter(MemoryBlockI* _memBlock)
- : m_memBlock(_memBlock)
- , m_data(NULL)
- , m_pos(0)
- , m_top(0)
- , m_size(0)
- {
- }
+ ///
+ MemoryWriter(MemoryBlockI* _memBlock);
- virtual ~MemoryWriter()
- {
- }
-
- virtual int64_t seek(int64_t _offset = 0, Whence::Enum _whence = Whence::Current) BX_OVERRIDE
- {
- switch (_whence)
- {
- case Whence::Begin:
- m_pos = int64_clamp(_offset, 0, m_top);
- break;
-
- case Whence::Current:
- m_pos = int64_clamp(m_pos + _offset, 0, m_top);
- break;
-
- case Whence::End:
- m_pos = int64_clamp(m_top - _offset, 0, m_top);
- break;
- }
+ ///
+ virtual ~MemoryWriter();
- return m_pos;
- }
+ ///
+ virtual int64_t seek(int64_t _offset = 0, Whence::Enum _whence = Whence::Current) BX_OVERRIDE;
- virtual int32_t write(const void* _data, int32_t _size, Error* _err) BX_OVERRIDE
- {
- BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
-
- int32_t morecore = int32_t(m_pos - m_size) + _size;
-
- if (0 < morecore)
- {
- morecore = BX_ALIGN_MASK(morecore, 0xfff);
- m_data = (uint8_t*)m_memBlock->more(morecore);
- m_size = m_memBlock->getSize();
- }
-
- int64_t remainder = m_size-m_pos;
- int32_t size = uint32_min(_size, uint32_t(int64_min(remainder, INT32_MAX) ) );
- memcpy(&m_data[m_pos], _data, size);
- m_pos += size;
- m_top = int64_max(m_top, m_pos);
- if (size != _size)
- {
- BX_ERROR_SET(_err, BX_ERROR_READERWRITER_WRITE, "MemoryWriter: write truncated.");
- }
- return size;
- }
+ ///
+ virtual int32_t write(const void* _data, int32_t _size, Error* _err) BX_OVERRIDE;
private:
MemoryBlockI* m_memBlock;
@@ -583,23 +223,86 @@ namespace bx
int64_t m_size;
};
+ ///
class StaticMemoryBlockWriter : public MemoryWriter
{
public:
- StaticMemoryBlockWriter(void* _data, uint32_t _size)
- : MemoryWriter(&m_smb)
- , m_smb(_data, _size)
- {
- }
+ ///
+ StaticMemoryBlockWriter(void* _data, uint32_t _size);
- ~StaticMemoryBlockWriter()
- {
- }
+ ///
+ virtual ~StaticMemoryBlockWriter();
private:
StaticMemoryBlock m_smb;
};
+ /// Read data.
+ int32_t read(ReaderI* _reader, void* _data, int32_t _size, Error* _err = NULL);
+
+ /// Read value.
+ template<typename Ty>
+ int32_t read(ReaderI* _reader, Ty& _value, Error* _err = NULL);
+
+ /// Read value and converts it to host endianess. _fromLittleEndian specifies
+ /// underlying stream endianess.
+ template<typename Ty>
+ int32_t readHE(ReaderI* _reader, Ty& _value, bool _fromLittleEndian, Error* _err = NULL);
+
+ /// Write data.
+ int32_t write(WriterI* _writer, const void* _data, int32_t _size, Error* _err = NULL);
+
+ /// Write repeat the same value.
+ int32_t writeRep(WriterI* _writer, uint8_t _byte, int32_t _size, Error* _err = NULL);
+
+ /// Write value.
+ template<typename Ty>
+ int32_t write(WriterI* _writer, const Ty& _value, Error* _err = NULL);
+
+ /// Write value as little endian.
+ template<typename Ty>
+ int32_t writeLE(WriterI* _writer, const Ty& _value, Error* _err = NULL);
+
+ /// Write value as big endian.
+ template<typename Ty>
+ int32_t writeBE(WriterI* _writer, const Ty& _value, Error* _err = NULL);
+
+ /// Write formated string.
+ int32_t writePrintf(WriterI* _writer, const char* _format, ...);
+
+ /// Skip _offset bytes forward.
+ int64_t skip(SeekerI* _seeker, int64_t _offset);
+
+ /// Seek to any position in file.
+ int64_t seek(SeekerI* _seeker, int64_t _offset = 0, Whence::Enum _whence = Whence::Current);
+
+ /// Returns size of file.
+ int64_t getSize(SeekerI* _seeker);
+
+ /// Peek data.
+ int32_t peek(ReaderSeekerI* _reader, void* _data, int32_t _size, Error* _err = NULL);
+
+ /// Peek value.
+ template<typename Ty>
+ int32_t peek(ReaderSeekerI* _reader, Ty& _value, Error* _err = NULL);
+
+ /// Align reader stream.
+ int32_t align(ReaderSeekerI* _reader, uint32_t _alignment, Error* _err = NULL);
+
+ /// Align writer stream (pads stream with zeros).
+ int32_t align(WriterSeekerI* _writer, uint32_t _alignment, Error* _err = NULL);
+
+ ///
+ bool open(ReaderOpenI* _reader, const char* _filePath, Error* _err = NULL);
+
+ ///
+ bool open(WriterOpenI* _writer, const char* _filePath, bool _append = false, Error* _err = NULL);
+
+ ///
+ void close(CloserI* _reader);
+
} // namespace bx
+#include "readerwriter.inl"
+
#endif // BX_READERWRITER_H_HEADER_GUARD
diff --git a/3rdparty/bx/include/bx/readerwriter.inl b/3rdparty/bx/include/bx/readerwriter.inl
new file mode 100644
index 00000000000..9ba8517776c
--- /dev/null
+++ b/3rdparty/bx/include/bx/readerwriter.inl
@@ -0,0 +1,452 @@
+/*
+ * Copyright 2010-2017 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ */
+
+#ifndef BX_READERWRITER_H_HEADER_GUARD
+# error "Must be included from bx/readerwriter!"
+#endif // BX_READERWRITER_H_HEADER_GUARD
+
+namespace bx
+{
+ inline ReaderI::~ReaderI()
+ {
+ }
+
+ inline WriterI::~WriterI()
+ {
+ }
+
+ inline SeekerI::~SeekerI()
+ {
+ }
+
+ inline ReaderOpenI::~ReaderOpenI()
+ {
+ }
+
+ inline WriterOpenI::~WriterOpenI()
+ {
+ }
+
+ inline CloserI::~CloserI()
+ {
+ }
+
+ inline StaticMemoryBlock::StaticMemoryBlock(void* _data, uint32_t _size)
+ : m_data(_data)
+ , m_size(_size)
+ {
+ }
+
+ inline StaticMemoryBlock::~StaticMemoryBlock()
+ {
+ }
+
+ inline void* StaticMemoryBlock::more(uint32_t _size)
+ {
+ BX_UNUSED(_size);
+ return m_data;
+ }
+
+ inline uint32_t StaticMemoryBlock::getSize()
+ {
+ return m_size;
+ }
+
+ inline MemoryBlock::MemoryBlock(AllocatorI* _allocator)
+ : m_allocator(_allocator)
+ , m_data(NULL)
+ , m_size(0)
+ {
+ }
+
+ inline MemoryBlock::~MemoryBlock()
+ {
+ BX_FREE(m_allocator, m_data);
+ }
+
+ inline void* MemoryBlock::more(uint32_t _size)
+ {
+ if (0 < _size)
+ {
+ m_size += _size;
+ m_data = BX_REALLOC(m_allocator, m_data, m_size);
+ }
+
+ return m_data;
+ }
+
+ inline uint32_t MemoryBlock::getSize()
+ {
+ return m_size;
+ }
+
+ inline SizerWriter::SizerWriter()
+ : m_pos(0)
+ , m_top(0)
+ {
+ }
+
+ inline SizerWriter::~SizerWriter()
+ {
+ }
+
+ inline int64_t SizerWriter::seek(int64_t _offset, Whence::Enum _whence)
+ {
+ switch (_whence)
+ {
+ case Whence::Begin:
+ m_pos = int64_clamp(_offset, 0, m_top);
+ break;
+
+ case Whence::Current:
+ m_pos = int64_clamp(m_pos + _offset, 0, m_top);
+ break;
+
+ case Whence::End:
+ m_pos = int64_clamp(m_top - _offset, 0, m_top);
+ break;
+ }
+
+ return m_pos;
+ }
+
+ inline int32_t SizerWriter::write(const void* /*_data*/, int32_t _size, Error* _err)
+ {
+ BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
+
+ int32_t morecore = int32_t(m_pos - m_top) + _size;
+
+ if (0 < morecore)
+ {
+ m_top += morecore;
+ }
+
+ int64_t remainder = m_top-m_pos;
+ int32_t size = uint32_min(_size, uint32_t(int64_min(remainder, INT32_MAX) ) );
+ m_pos += size;
+ if (size != _size)
+ {
+ BX_ERROR_SET(_err, BX_ERROR_READERWRITER_WRITE, "SizerWriter: write truncated.");
+ }
+ return size;
+ }
+
+ inline MemoryReader::MemoryReader(const void* _data, uint32_t _size)
+ : m_data( (const uint8_t*)_data)
+ , m_pos(0)
+ , m_top(_size)
+ {
+ }
+
+ inline MemoryReader::~MemoryReader()
+ {
+ }
+
+ inline int64_t MemoryReader::seek(int64_t _offset, Whence::Enum _whence)
+ {
+ switch (_whence)
+ {
+ case Whence::Begin:
+ m_pos = int64_clamp(_offset, 0, m_top);
+ break;
+
+ case Whence::Current:
+ m_pos = int64_clamp(m_pos + _offset, 0, m_top);
+ break;
+
+ case Whence::End:
+ m_pos = int64_clamp(m_top - _offset, 0, m_top);
+ break;
+ }
+
+ return m_pos;
+ }
+
+ inline int32_t MemoryReader::read(void* _data, int32_t _size, Error* _err)
+ {
+ BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
+
+ int64_t remainder = m_top-m_pos;
+ int32_t size = uint32_min(_size, uint32_t(int64_min(remainder, INT32_MAX) ) );
+ memcpy(_data, &m_data[m_pos], size);
+ m_pos += size;
+ if (size != _size)
+ {
+ BX_ERROR_SET(_err, BX_ERROR_READERWRITER_READ, "MemoryReader: read truncated.");
+ }
+ return size;
+ }
+
+ inline const uint8_t* MemoryReader::getDataPtr() const
+ {
+ return &m_data[m_pos];
+ }
+
+ inline int64_t MemoryReader::getPos() const
+ {
+ return m_pos;
+ }
+
+ inline int64_t MemoryReader::remaining() const
+ {
+ return m_top-m_pos;
+ }
+
+ inline MemoryWriter::MemoryWriter(MemoryBlockI* _memBlock)
+ : m_memBlock(_memBlock)
+ , m_data(NULL)
+ , m_pos(0)
+ , m_top(0)
+ , m_size(0)
+ {
+ }
+
+ inline MemoryWriter::~MemoryWriter()
+ {
+ }
+
+ inline int64_t MemoryWriter::seek(int64_t _offset, Whence::Enum _whence)
+ {
+ switch (_whence)
+ {
+ case Whence::Begin:
+ m_pos = int64_clamp(_offset, 0, m_top);
+ break;
+
+ case Whence::Current:
+ m_pos = int64_clamp(m_pos + _offset, 0, m_top);
+ break;
+
+ case Whence::End:
+ m_pos = int64_clamp(m_top - _offset, 0, m_top);
+ break;
+ }
+
+ return m_pos;
+ }
+
+ inline int32_t MemoryWriter::write(const void* _data, int32_t _size, Error* _err)
+ {
+ BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
+
+ int32_t morecore = int32_t(m_pos - m_size) + _size;
+
+ if (0 < morecore)
+ {
+ morecore = BX_ALIGN_MASK(morecore, 0xfff);
+ m_data = (uint8_t*)m_memBlock->more(morecore);
+ m_size = m_memBlock->getSize();
+ }
+
+ int64_t remainder = m_size-m_pos;
+ int32_t size = uint32_min(_size, uint32_t(int64_min(remainder, INT32_MAX) ) );
+ memcpy(&m_data[m_pos], _data, size);
+ m_pos += size;
+ m_top = int64_max(m_top, m_pos);
+ if (size != _size)
+ {
+ BX_ERROR_SET(_err, BX_ERROR_READERWRITER_WRITE, "MemoryWriter: write truncated.");
+ }
+ return size;
+ }
+
+ inline StaticMemoryBlockWriter::StaticMemoryBlockWriter(void* _data, uint32_t _size)
+ : MemoryWriter(&m_smb)
+ , m_smb(_data, _size)
+ {
+ }
+
+ inline StaticMemoryBlockWriter::~StaticMemoryBlockWriter()
+ {
+ }
+
+ inline int32_t read(ReaderI* _reader, void* _data, int32_t _size, Error* _err)
+ {
+ BX_ERROR_SCOPE(_err);
+ return _reader->read(_data, _size, _err);
+ }
+
+ template<typename Ty>
+ int32_t read(ReaderI* _reader, Ty& _value, Error* _err)
+ {
+ BX_ERROR_SCOPE(_err);
+ BX_STATIC_ASSERT(BX_TYPE_IS_POD(Ty) );
+ return _reader->read(&_value, sizeof(Ty), _err);
+ }
+
+ template<typename Ty>
+ int32_t readHE(ReaderI* _reader, Ty& _value, bool _fromLittleEndian, Error* _err)
+ {
+ BX_ERROR_SCOPE(_err);
+ BX_STATIC_ASSERT(BX_TYPE_IS_POD(Ty) );
+ Ty value;
+ int32_t result = _reader->read(&value, sizeof(Ty), _err);
+ _value = toHostEndian(value, _fromLittleEndian);
+ return result;
+ }
+
+ inline int32_t write(WriterI* _writer, const void* _data, int32_t _size, Error* _err)
+ {
+ BX_ERROR_SCOPE(_err);
+ return _writer->write(_data, _size, _err);
+ }
+
+ inline int32_t writeRep(WriterI* _writer, uint8_t _byte, int32_t _size, Error* _err)
+ {
+ BX_ERROR_SCOPE(_err);
+
+ const uint32_t tmp0 = uint32_sels(64 - _size, 64, _size);
+ const uint32_t tmp1 = uint32_sels(256 - _size, 256, tmp0);
+ const uint32_t blockSize = uint32_sels(1024 - _size, 1024, tmp1);
+ uint8_t* temp = (uint8_t*)alloca(blockSize);
+ memset(temp, _byte, blockSize);
+
+ int32_t size = 0;
+ while (0 < _size)
+ {
+ int32_t bytes = write(_writer, temp, uint32_min(blockSize, _size), _err);
+ size += bytes;
+ _size -= bytes;
+ }
+
+ return size;
+ }
+
+ template<typename Ty>
+ int32_t write(WriterI* _writer, const Ty& _value, Error* _err)
+ {
+ BX_ERROR_SCOPE(_err);
+ BX_STATIC_ASSERT(BX_TYPE_IS_POD(Ty) );
+ return _writer->write(&_value, sizeof(Ty), _err);
+ }
+
+ template<typename Ty>
+ int32_t writeLE(WriterI* _writer, const Ty& _value, Error* _err)
+ {
+ BX_ERROR_SCOPE(_err);
+ BX_STATIC_ASSERT(BX_TYPE_IS_POD(Ty) );
+ Ty value = toLittleEndian(_value);
+ int32_t result = _writer->write(&value, sizeof(Ty), _err);
+ return result;
+ }
+
+ template<typename Ty>
+ int32_t writeBE(WriterI* _writer, const Ty& _value, Error* _err)
+ {
+ BX_ERROR_SCOPE(_err);
+ BX_STATIC_ASSERT(BX_TYPE_IS_POD(Ty) );
+ Ty value = toBigEndian(_value);
+ int32_t result = _writer->write(&value, sizeof(Ty), _err);
+ return result;
+ }
+
+ inline int32_t writePrintf(WriterI* _writer, const char* _format, ...)
+ {
+ va_list argList;
+ va_start(argList, _format);
+
+ char temp[2048];
+ char* out = temp;
+ int32_t max = sizeof(temp);
+ int32_t len = vsnprintf(out, max, _format, argList);
+ if (len > max)
+ {
+ out = (char*)alloca(len);
+ len = vsnprintf(out, len, _format, argList);
+ }
+
+ int32_t size = write(_writer, out, len);
+
+ va_end(argList);
+
+ return size;
+ }
+
+ inline int64_t skip(SeekerI* _seeker, int64_t _offset)
+ {
+ return _seeker->seek(_offset, Whence::Current);
+ }
+
+ inline int64_t seek(SeekerI* _seeker, int64_t _offset, Whence::Enum _whence)
+ {
+ return _seeker->seek(_offset, _whence);
+ }
+
+ inline int64_t getSize(SeekerI* _seeker)
+ {
+ int64_t offset = _seeker->seek();
+ int64_t size = _seeker->seek(0, Whence::End);
+ _seeker->seek(offset, Whence::Begin);
+ return size;
+ }
+
+ inline int32_t peek(ReaderSeekerI* _reader, void* _data, int32_t _size, Error* _err)
+ {
+ BX_ERROR_SCOPE(_err);
+ int64_t offset = bx::seek(_reader);
+ int32_t size = _reader->read(_data, _size, _err);
+ bx::seek(_reader, offset, bx::Whence::Begin);
+ return size;
+ }
+
+ template<typename Ty>
+ int32_t peek(ReaderSeekerI* _reader, Ty& _value, Error* _err)
+ {
+ BX_ERROR_SCOPE(_err);
+ BX_STATIC_ASSERT(BX_TYPE_IS_POD(Ty) );
+ return peek(_reader, &_value, sizeof(Ty), _err);
+ }
+
+ inline int32_t align(ReaderSeekerI* _reader, uint32_t _alignment, Error* _err)
+ {
+ BX_ERROR_SCOPE(_err);
+ const int64_t current = bx::seek(_reader);
+ const int64_t aligned = ( (current + _alignment-1)/_alignment) * _alignment;
+ const int32_t size = int32_t(aligned - current);
+ if (0 != size)
+ {
+ const int64_t offset = bx::seek(_reader, size);
+ if (offset != aligned)
+ {
+ BX_ERROR_SET(_err, BX_ERROR_READERWRITER_WRITE, "Align: read truncated.");
+ }
+ return int32_t(offset - current);
+ }
+
+ return 0;
+ }
+
+ inline int32_t align(WriterSeekerI* _writer, uint32_t _alignment, Error* _err)
+ {
+ BX_ERROR_SCOPE(_err);
+ const int64_t current = bx::seek(_writer);
+ const int64_t aligned = ( (current + _alignment-1)/_alignment) * _alignment;
+ const int32_t size = int32_t(aligned - current);
+ if (0 != size)
+ {
+ return writeRep(_writer, 0, size, _err);
+ }
+
+ return 0;
+ }
+
+ inline bool open(ReaderOpenI* _reader, const char* _filePath, Error* _err)
+ {
+ BX_ERROR_USE_TEMP_WHEN_NULL(_err);
+ return _reader->open(_filePath, _err);
+ }
+
+ inline bool open(WriterOpenI* _writer, const char* _filePath, bool _append, Error* _err)
+ {
+ BX_ERROR_USE_TEMP_WHEN_NULL(_err);
+ return _writer->open(_filePath, _append, _err);
+ }
+
+ inline void close(CloserI* _reader)
+ {
+ _reader->close();
+ }
+
+} // namespace bx
diff --git a/3rdparty/bx/include/bx/rng.h b/3rdparty/bx/include/bx/rng.h
index cff323c2f95..91eade62644 100644
--- a/3rdparty/bx/include/bx/rng.h
+++ b/3rdparty/bx/include/bx/rng.h
@@ -12,83 +12,54 @@
namespace bx
{
- // George Marsaglia's MWC
+ /// George Marsaglia's MWC
class RngMwc
{
public:
- RngMwc(uint32_t _z = 12345, uint32_t _w = 65435)
- : m_z(_z)
- , m_w(_w)
- {
- }
-
- void reset(uint32_t _z = 12345, uint32_t _w = 65435)
- {
- m_z = _z;
- m_w = _w;
- }
-
- uint32_t gen()
- {
- m_z = 36969*(m_z&65535)+(m_z>>16);
- m_w = 18000*(m_w&65535)+(m_w>>16);
- return (m_z<<16)+m_w;
- }
+ ///
+ RngMwc(uint32_t _z = 12345, uint32_t _w = 65435);
+
+ ///
+ void reset(uint32_t _z = 12345, uint32_t _w = 65435);
+
+ ///
+ uint32_t gen();
private:
uint32_t m_z;
uint32_t m_w;
};
- // George Marsaglia's FIB
+ /// George Marsaglia's FIB
class RngFib
{
public:
- RngFib()
- : m_a(9983651)
- , m_b(95746118)
- {
- }
-
- void reset()
- {
- m_a = 9983651;
- m_b = 95746118;
- }
-
- uint32_t gen()
- {
- m_b = m_a+m_b;
- m_a = m_b-m_a;
- return m_a;
- }
+ ///
+ RngFib(uint32_t _a = 9983651, uint32_t _b = 95746118);
+
+ ///
+ void reset(uint32_t _a = 9983651, uint32_t _b = 95746118);
+
+ ///
+ uint32_t gen();
private:
uint32_t m_a;
uint32_t m_b;
};
- // George Marsaglia's SHR3
+ /// George Marsaglia's SHR3
class RngShr3
{
public:
- RngShr3(uint32_t _jsr = 34221)
- : m_jsr(_jsr)
- {
- }
-
- void reset(uint32_t _jsr = 34221)
- {
- m_jsr = _jsr;
- }
-
- uint32_t gen()
- {
- m_jsr ^= m_jsr<<17;
- m_jsr ^= m_jsr>>13;
- m_jsr ^= m_jsr<<5;
- return m_jsr;
- }
+ ///
+ RngShr3(uint32_t _jsr = 34221);
+
+ ///
+ void reset(uint32_t _jsr = 34221);
+
+ ///
+ uint32_t gen();
private:
uint32_t m_jsr;
@@ -96,112 +67,35 @@ namespace bx
/// Returns random number between 0.0f and 1.0f.
template <typename Rng>
- inline float frnd(Rng* _rng)
- {
- uint32_t rnd = _rng->gen() & UINT16_MAX;
- return float(rnd) * 1.0f/float(UINT16_MAX);
- }
+ float frnd(Rng* _rng);
/// Returns random number between -1.0f and 1.0f.
template <typename Rng>
- inline float frndh(Rng* _rng)
- {
- return 2.0f * bx::frnd(_rng) - 1.0f;
- }
+ float frndh(Rng* _rng);
/// Generate random point on unit circle.
template <typename Rng>
- inline void randUnitCircle(float _result[3], Rng* _rng)
- {
- const float angle = frnd(_rng) * pi * 2.0f;
-
- _result[0] = fcos(angle);
- _result[1] = 0.0f;
- _result[2] = fsin(angle);
- }
+ void randUnitCircle(float _result[3], Rng* _rng);
/// Generate random point on unit sphere.
template <typename Rng>
- inline void randUnitSphere(float _result[3], Rng* _rng)
- {
- const float rand0 = frnd(_rng) * 2.0f - 1.0f;
- const float rand1 = frnd(_rng) * pi * 2.0f;
- const float sqrtf1 = fsqrt(1.0f - rand0*rand0);
-
- _result[0] = sqrtf1 * fcos(rand1);
- _result[1] = sqrtf1 * fsin(rand1);
- _result[2] = rand0;
- }
+ void randUnitSphere(float _result[3], Rng* _rng);
/// Generate random point on unit hemisphere.
template <typename Ty>
- inline void randUnitHemisphere(float _result[3], Ty* _rng, const float _normal[3])
- {
- float dir[3];
- randUnitSphere(dir, _rng);
-
- float DdotN = dir[0]*_normal[0]
- + dir[1]*_normal[1]
- + dir[2]*_normal[2]
- ;
-
- if (0.0f > DdotN)
- {
- dir[0] = -dir[0];
- dir[1] = -dir[1];
- dir[2] = -dir[2];
- }
-
- _result[0] = dir[0];
- _result[1] = dir[1];
- _result[2] = dir[2];
- }
+ void randUnitHemisphere(float _result[3], Ty* _rng, const float _normal[3]);
/// Sampling with Hammersley and Halton Points
/// http://www.cse.cuhk.edu.hk/~ttwong/papers/udpoint/udpoints.html
///
- inline void generateSphereHammersley(void* _data, uint32_t _stride, uint32_t _num, float _scale = 1.0f)
- {
- uint8_t* data = (uint8_t*)_data;
-
- for (uint32_t ii = 0; ii < _num; ii++)
- {
- float tt = 0.0f;
- float pp = 0.5;
- for (uint32_t jj = ii; jj; jj >>= 1)
- {
- tt += (jj & 1) ? pp : 0.0f;
- pp *= 0.5f;
- }
-
- tt = 2.0f * tt - 1.0f;
-
- const float phi = (ii + 0.5f) / _num;
- const float phirad = phi * 2.0f * pi;
- const float st = fsqrt(1.0f-tt*tt) * _scale;
-
- float* xyz = (float*)data;
- data += _stride;
-
- xyz[0] = st * fcos(phirad);
- xyz[1] = st * fsin(phirad);
- xyz[2] = tt * _scale;
- }
- }
+ void generateSphereHammersley(void* _data, uint32_t _stride, uint32_t _num, float _scale = 1.0f);
/// Fisher-Yates shuffle.
template<typename Rng, typename Ty>
- inline void shuffle(Rng* _rng, Ty* _array, uint32_t _num)
- {
- BX_CHECK(_num != 0, "Number of elements can't be 0!");
-
- for (uint32_t ii = 0, num = _num-1; ii < num; ++ii)
- {
- uint32_t jj = ii + 1 + _rng->gen() % (num - ii);
- bx::xchg(_array[ii], _array[jj]);
- }
- }
+ void shuffle(Rng* _rng, Ty* _array, uint32_t _num);
} // namespace bx
+#include "rng.inl"
+
#endif // BX_RNG_H_HEADER_GUARD
diff --git a/3rdparty/bx/include/bx/rng.inl b/3rdparty/bx/include/bx/rng.inl
new file mode 100644
index 00000000000..02a4d21e5bc
--- /dev/null
+++ b/3rdparty/bx/include/bx/rng.inl
@@ -0,0 +1,171 @@
+/*
+ * Copyright 2010-2017 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ */
+
+#ifndef BX_RNG_H_HEADER_GUARD
+# error "Must be included from bx/rng.h!"
+#endif // BX_RNG_H_HEADER_GUARD
+
+#include "bx.h"
+#include "fpumath.h"
+#include "uint32_t.h"
+
+namespace bx
+{
+ inline RngMwc::RngMwc(uint32_t _z, uint32_t _w)
+ : m_z(_z)
+ , m_w(_w)
+ {
+ }
+
+ inline void RngMwc::reset(uint32_t _z, uint32_t _w)
+ {
+ m_z = _z;
+ m_w = _w;
+ }
+
+ inline uint32_t RngMwc::gen()
+ {
+ m_z = 36969*(m_z&65535)+(m_z>>16);
+ m_w = 18000*(m_w&65535)+(m_w>>16);
+ return (m_z<<16)+m_w;
+ }
+
+ inline RngFib::RngFib(uint32_t _a, uint32_t _b)
+ : m_a(_a)
+ , m_b(_b)
+ {
+ }
+
+ inline void RngFib::reset(uint32_t _a, uint32_t _b)
+ {
+ m_a = _a;
+ m_b = _b;
+ }
+
+ inline uint32_t RngFib::gen()
+ {
+ m_b = m_a+m_b;
+ m_a = m_b-m_a;
+ return m_a;
+ }
+
+ inline RngShr3::RngShr3(uint32_t _jsr)
+ : m_jsr(_jsr)
+ {
+ }
+
+ inline void RngShr3::reset(uint32_t _jsr)
+ {
+ m_jsr = _jsr;
+ }
+
+ inline uint32_t RngShr3::gen()
+ {
+ m_jsr ^= m_jsr<<17;
+ m_jsr ^= m_jsr>>13;
+ m_jsr ^= m_jsr<<5;
+ return m_jsr;
+ }
+
+ template <typename Rng>
+ inline float frnd(Rng* _rng)
+ {
+ uint32_t rnd = _rng->gen() & UINT16_MAX;
+ return float(rnd) * 1.0f/float(UINT16_MAX);
+ }
+
+ template <typename Rng>
+ inline float frndh(Rng* _rng)
+ {
+ return 2.0f * bx::frnd(_rng) - 1.0f;
+ }
+
+ template <typename Rng>
+ inline void randUnitCircle(float _result[3], Rng* _rng)
+ {
+ const float angle = frnd(_rng) * pi * 2.0f;
+
+ _result[0] = fcos(angle);
+ _result[1] = 0.0f;
+ _result[2] = fsin(angle);
+ }
+
+ template <typename Rng>
+ inline void randUnitSphere(float _result[3], Rng* _rng)
+ {
+ const float rand0 = frnd(_rng) * 2.0f - 1.0f;
+ const float rand1 = frnd(_rng) * pi * 2.0f;
+ const float sqrtf1 = fsqrt(1.0f - rand0*rand0);
+
+ _result[0] = sqrtf1 * fcos(rand1);
+ _result[1] = sqrtf1 * fsin(rand1);
+ _result[2] = rand0;
+ }
+
+ template <typename Ty>
+ inline void randUnitHemisphere(float _result[3], Ty* _rng, const float _normal[3])
+ {
+ float dir[3];
+ randUnitSphere(dir, _rng);
+
+ float DdotN = dir[0]*_normal[0]
+ + dir[1]*_normal[1]
+ + dir[2]*_normal[2]
+ ;
+
+ if (0.0f > DdotN)
+ {
+ dir[0] = -dir[0];
+ dir[1] = -dir[1];
+ dir[2] = -dir[2];
+ }
+
+ _result[0] = dir[0];
+ _result[1] = dir[1];
+ _result[2] = dir[2];
+ }
+
+ inline void generateSphereHammersley(void* _data, uint32_t _stride, uint32_t _num, float _scale)
+ {
+ uint8_t* data = (uint8_t*)_data;
+
+ for (uint32_t ii = 0; ii < _num; ii++)
+ {
+ float tt = 0.0f;
+ float pp = 0.5;
+ for (uint32_t jj = ii; jj; jj >>= 1)
+ {
+ tt += (jj & 1) ? pp : 0.0f;
+ pp *= 0.5f;
+ }
+
+ tt = 2.0f * tt - 1.0f;
+
+ const float phi = (ii + 0.5f) / _num;
+ const float phirad = phi * 2.0f * pi;
+ const float st = fsqrt(1.0f-tt*tt) * _scale;
+
+ float* xyz = (float*)data;
+ data += _stride;
+
+ xyz[0] = st * fcos(phirad);
+ xyz[1] = st * fsin(phirad);
+ xyz[2] = tt * _scale;
+ }
+ }
+
+ template<typename Rng, typename Ty>
+ inline void shuffle(Rng* _rng, Ty* _array, uint32_t _num)
+ {
+ BX_CHECK(_num != 0, "Number of elements can't be 0!");
+
+ for (uint32_t ii = 0, num = _num-1; ii < num; ++ii)
+ {
+ uint32_t jj = ii + 1 + _rng->gen() % (num - ii);
+ bx::xchg(_array[ii], _array[jj]);
+ }
+ }
+
+} // namespace bx
diff --git a/3rdparty/bx/include/bx/sem.h b/3rdparty/bx/include/bx/sem.h
index b33ab3721b0..acc2359c363 100644
--- a/3rdparty/bx/include/bx/sem.h
+++ b/3rdparty/bx/include/bx/sem.h
@@ -7,7 +7,6 @@
#define BX_SEM_H_HEADER_GUARD
#include "bx.h"
-#include "mutex.h"
#if BX_CONFIG_SUPPORTS_THREADING
@@ -16,18 +15,19 @@
# include <semaphore.h>
# include <time.h>
# include <pthread.h>
-#elif BX_PLATFORM_XBOXONE
-# include <synchapi.h>
-#elif BX_PLATFORM_XBOX360 || BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT
+#elif BX_PLATFORM_XBOX360 || BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT || BX_PLATFORM_XBOXONE
# include <windows.h>
# include <limits.h>
+# if BX_PLATFORM_XBOXONE
+# include <synchapi.h>
+# endif // BX_PLATFORM_XBOXONE
#endif // BX_PLATFORM_
+#include "mutex.h"
+
namespace bx
{
-#if BX_PLATFORM_POSIX
-
-# if BX_CONFIG_SEMAPHORE_PTHREAD
+ ///
class Semaphore
{
BX_CLASS(Semaphore
@@ -36,228 +36,31 @@ namespace bx
);
public:
- Semaphore()
- : m_count(0)
- {
- int result;
- result = pthread_mutex_init(&m_mutex, NULL);
- BX_CHECK(0 == result, "pthread_mutex_init %d", result);
-
- result = pthread_cond_init(&m_cond, NULL);
- BX_CHECK(0 == result, "pthread_cond_init %d", result);
-
- BX_UNUSED(result);
- }
-
- ~Semaphore()
- {
- int result;
- result = pthread_cond_destroy(&m_cond);
- BX_CHECK(0 == result, "pthread_cond_destroy %d", result);
-
- result = pthread_mutex_destroy(&m_mutex);
- BX_CHECK(0 == result, "pthread_mutex_destroy %d", result);
-
- BX_UNUSED(result);
- }
-
- void post(uint32_t _count = 1)
- {
- int result = pthread_mutex_lock(&m_mutex);
- BX_CHECK(0 == result, "pthread_mutex_lock %d", result);
-
- for (uint32_t ii = 0; ii < _count; ++ii)
- {
- result = pthread_cond_signal(&m_cond);
- BX_CHECK(0 == result, "pthread_cond_signal %d", result);
- }
-
- m_count += _count;
-
- result = pthread_mutex_unlock(&m_mutex);
- BX_CHECK(0 == result, "pthread_mutex_unlock %d", result);
+ ///
+ Semaphore();
- BX_UNUSED(result);
- }
+ ///
+ ~Semaphore();
- bool wait(int32_t _msecs = -1)
- {
- int result = pthread_mutex_lock(&m_mutex);
- BX_CHECK(0 == result, "pthread_mutex_lock %d", result);
+ ///
+ void post(uint32_t _count = 1);
-# if BX_PLATFORM_NACL || BX_PLATFORM_OSX
- BX_UNUSED(_msecs);
- BX_CHECK(-1 == _msecs, "NaCl and OSX don't support pthread_cond_timedwait at this moment.");
- while (0 == result
- && 0 >= m_count)
- {
- result = pthread_cond_wait(&m_cond, &m_mutex);
- }
-# elif BX_PLATFORM_IOS
- if (-1 == _msecs)
- {
- while (0 == result
- && 0 >= m_count)
- {
- result = pthread_cond_wait(&m_cond, &m_mutex);
- }
- }
- else
- {
- timespec ts;
- ts.tv_sec = _msecs/1000;
- ts.tv_nsec = (_msecs%1000)*1000;
-
- while (0 == result
- && 0 >= m_count)
- {
- result = pthread_cond_timedwait_relative_np(&m_cond, &m_mutex, &ts);
- }
- }
-# else
- timespec ts;
- clock_gettime(CLOCK_REALTIME, &ts);
- ts.tv_sec += _msecs/1000;
- ts.tv_nsec += (_msecs%1000)*1000;
-
- while (0 == result
- && 0 >= m_count)
- {
- result = pthread_cond_timedwait(&m_cond, &m_mutex, &ts);
- }
-# endif // BX_PLATFORM_NACL || BX_PLATFORM_OSX
- bool ok = 0 == result;
-
- if (ok)
- {
- --m_count;
- }
-
- result = pthread_mutex_unlock(&m_mutex);
- BX_CHECK(0 == result, "pthread_mutex_unlock %d", result);
-
- BX_UNUSED(result);
-
- return ok;
- }
+ ///
+ bool wait(int32_t _msecs = -1);
private:
+#if BX_PLATFORM_POSIX
+# if BX_CONFIG_SEMAPHORE_PTHREAD
pthread_mutex_t m_mutex;
pthread_cond_t m_cond;
int32_t m_count;
- };
-
# else
-
- class Semaphore
- {
- BX_CLASS(Semaphore
- , NO_COPY
- , NO_ASSIGNMENT
- );
-
- public:
- Semaphore()
- {
- int32_t result = sem_init(&m_handle, 0, 0);
- BX_CHECK(0 == result, "sem_init failed. errno %d", errno);
- BX_UNUSED(result);
- }
-
- ~Semaphore()
- {
- int32_t result = sem_destroy(&m_handle);
- BX_CHECK(0 == result, "sem_destroy failed. errno %d", errno);
- BX_UNUSED(result);
- }
-
- void post(uint32_t _count = 1)
- {
- int32_t result;
- for (uint32_t ii = 0; ii < _count; ++ii)
- {
- result = sem_post(&m_handle);
- BX_CHECK(0 == result, "sem_post failed. errno %d", errno);
- }
- BX_UNUSED(result);
- }
-
- bool wait(int32_t _msecs = -1)
- {
-# if BX_PLATFORM_NACL || BX_PLATFORM_OSX
- BX_CHECK(-1 == _msecs, "NaCl and OSX don't support sem_timedwait at this moment."); BX_UNUSED(_msecs);
- return 0 == sem_wait(&m_handle);
-# else
- if (0 > _msecs)
- {
- int32_t result;
- do
- {
- result = sem_wait(&m_handle);
- } // keep waiting when interrupted by a signal handler...
- while (-1 == result && EINTR == errno);
- BX_CHECK(0 == result, "sem_wait failed. errno %d", errno);
- return 0 == result;
- }
-
- timespec ts;
- clock_gettime(CLOCK_REALTIME, &ts);
- ts.tv_sec += _msecs/1000;
- ts.tv_nsec += (_msecs%1000)*1000;
- return 0 == sem_timedwait(&m_handle, &ts);
-# endif // BX_PLATFORM_
- }
-
- private:
sem_t m_handle;
- };
# endif // BX_CONFIG_SEMAPHORE_PTHREAD
-
#elif BX_PLATFORM_XBOX360 || BX_PLATFORM_XBOXONE || BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT
-
- class Semaphore
- {
- BX_CLASS(Semaphore
- , NO_COPY
- , NO_ASSIGNMENT
- );
-
- public:
- Semaphore()
- {
-#if BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT
- m_handle = CreateSemaphoreExW(NULL, 0, LONG_MAX, NULL, 0, SEMAPHORE_ALL_ACCESS);
-#else
- m_handle = CreateSemaphoreA(NULL, 0, LONG_MAX, NULL);
-#endif
- BX_CHECK(NULL != m_handle, "Failed to create Semaphore!");
- }
-
- ~Semaphore()
- {
- CloseHandle(m_handle);
- }
-
- void post(uint32_t _count = 1) const
- {
- ReleaseSemaphore(m_handle, _count, NULL);
- }
-
- bool wait(int32_t _msecs = -1) const
- {
- DWORD milliseconds = (0 > _msecs) ? INFINITE : _msecs;
-#if BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT
- return WAIT_OBJECT_0 == WaitForSingleObjectEx(m_handle, milliseconds, FALSE);
-#else
- return WAIT_OBJECT_0 == WaitForSingleObject(m_handle, milliseconds);
-#endif
- }
-
- private:
HANDLE m_handle;
- };
-
#endif // BX_PLATFORM_
+ };
} // namespace bx
diff --git a/3rdparty/bx/include/bx/simd256_avx.inl b/3rdparty/bx/include/bx/simd256_avx.inl
index 2a31c83f5ae..5eed77ba3af 100644
--- a/3rdparty/bx/include/bx/simd256_avx.inl
+++ b/3rdparty/bx/include/bx/simd256_avx.inl
@@ -46,7 +46,7 @@ namespace bx
template<>
BX_SIMD_FORCE_INLINE simd256_avx_t simd_isplat(uint32_t _a)
{
- const __m256i splat = _mm256_set1_epi32(_a);
+ const __m256i splat = _mm256_set1_epi32(_a);
const simd256_avx_t result = _mm256_castsi256_ps(splat);
return result;
@@ -55,7 +55,7 @@ namespace bx
template<>
BX_SIMD_FORCE_INLINE simd256_avx_t simd_itof(simd256_avx_t _a)
{
- const __m256i itof = _mm256_castps_si256(_a);
+ const __m256i itof = _mm256_castps_si256(_a);
const simd256_avx_t result = _mm256_cvtepi32_ps(itof);
return result;
@@ -64,7 +64,7 @@ namespace bx
template<>
BX_SIMD_FORCE_INLINE simd256_avx_t simd_ftoi(simd256_avx_t _a)
{
- const __m256i ftoi = _mm256_cvtps_epi32(_a);
+ const __m256i ftoi = _mm256_cvtps_epi32(_a);
const simd256_avx_t result = _mm256_castsi256_ps(ftoi);
return result;
diff --git a/3rdparty/bx/include/bx/string.h b/3rdparty/bx/include/bx/string.h
index 44002f55250..eaf27bc983c 100644
--- a/3rdparty/bx/include/bx/string.h
+++ b/3rdparty/bx/include/bx/string.h
@@ -8,696 +8,234 @@
#include "bx.h"
#include <alloca.h>
-#include <ctype.h> // tolower
#include <stdarg.h> // va_list
-#include <stdio.h> // vsnprintf, vsnwprintf
-#include <string.h>
#include <wchar.h> // wchar_t
#include <bx/allocator.h>
#include <bx/hash.h>
-#ifndef va_copy
-# define va_copy(_a, _b) (_a) = (_b)
-#endif // va_copy
-
namespace bx
{
- ///
- inline bool toBool(const char* _str)
+ /// Non-zero-terminated string view.
+ class StringView
{
- char ch = (char)::tolower(_str[0]);
- return ch == 't' || ch == '1';
- }
+ public:
+ ///
+ StringView();
- /// Case insensitive string compare.
- inline int32_t stricmp(const char* _a, const char* _b)
+ ///
+ StringView(const StringView& _rhs);
+
+ ///
+ StringView& operator=(const StringView& _rhs);
+
+ ///
+ StringView(const char* _ptr, uint32_t _len = UINT16_MAX);
+
+ ///
+ void set(const char* _ptr, uint32_t _len = UINT16_MAX);
+
+ ///
+ void clear();
+
+ ///
+ const char* getPtr() const;
+
+ ///
+ const char* getTerm() const;
+
+ ///
+ bool isEmpty() const;
+
+ ///
+ uint32_t getLength() const;
+
+ protected:
+ const char* m_ptr;
+ uint32_t m_len;
+ };
+
+ /// ASCII string
+ template<bx::AllocatorI** AllocatorT>
+ class StringT : public StringView
{
-#if BX_CRT_MSVC
- return ::_stricmp(_a, _b);
-#else
- return ::strcasecmp(_a, _b);
-#endif // BX_COMPILER_
- }
+ public:
+ ///
+ StringT();
+
+ ///
+ StringT(const StringT<AllocatorT>& _rhs);
+
+ ///
+ StringT<AllocatorT>& operator=(const StringT<AllocatorT>& _rhs);
+
+ ///
+ StringT(const char* _ptr, uint32_t _len = UINT32_MAX);
+
+ ///
+ StringT(const StringView& _rhs);
+
+ ///
+ ~StringT();
+
+ ///
+ void set(const char* _ptr, uint32_t _len = UINT32_MAX);
+
+ ///
+ void append(const char* _ptr, uint32_t _len = UINT32_MAX);
+
+ ///
+ void clear();
+ };
///
- inline size_t strnlen(const char* _str, size_t _max)
- {
- const char* ptr;
- for (ptr = _str; 0 < _max && *ptr != '\0'; ++ptr, --_max) {};
- return ptr - _str;
- }
+ bool isSpace(char _ch);
+
+ ///
+ bool isUpper(char _ch);
+
+ ///
+ bool isLower(char _ch);
+
+ ///
+ bool isAlpha(char _ch);
+
+ ///
+ bool isNumeric(char _ch);
+
+ ///
+ bool isAlphaNum(char _ch);
+
+ ///
+ bool isPrint(char _ch);
+
+ ///
+ char toLower(char _ch);
+
+ ///
+ char toUpper(char _ch);
+
+ ///
+ bool toBool(const char* _str);
+
+ /// String compare.
+ int32_t strncmp(const char* _lhs, const char* _rhs, size_t _max = INT32_MAX);
+
+ /// Case insensitive string compare.
+ int32_t strincmp(const char* _lhs, const char* _rhs, size_t _max = INT32_MAX);
+
+ ///
+ size_t strnlen(const char* _str, size_t _max = -1);
/// Copy _num characters from string _src to _dst buffer of maximum _dstSize capacity
/// including zero terminator. Copy will be terminated with '\0'.
- inline size_t strlncpy(char* _dst, size_t _dstSize, const char* _src, size_t _num = -1)
- {
- BX_CHECK(NULL != _dst, "_dst can't be NULL!");
- BX_CHECK(NULL != _src, "_src can't be NULL!");
- BX_CHECK(0 < _dstSize, "_dstSize can't be 0!");
+ size_t strlncpy(char* _dst, size_t _dstSize, const char* _src, size_t _num = INT32_MAX);
- const size_t len = strnlen(_src, _num);
- const size_t max = _dstSize-1;
- const size_t num = (len < max ? len : max);
- strncpy(_dst, _src, num);
- _dst[num] = '\0';
+ ///
+ size_t strlncat(char* _dst, size_t _dstSize, const char* _src, size_t _num = INT32_MAX);
+
+ ///
+ const char* strnchr(const char* _str, char _ch, size_t _max = INT32_MAX);
- return num;
- }
+ ///
+ const char* strnrchr(const char* _str, char _ch, size_t _max = INT32_MAX);
/// Find substring in string. Limit search to _size.
- inline const char* strnstr(const char* _str, const char* _find, size_t _size)
- {
- char first = *_find;
- if ('\0' == first)
- {
- return _str;
- }
-
- const char* cmp = _find + 1;
- size_t len = strlen(cmp);
- do
- {
- for (char match = *_str++; match != first && 0 < _size; match = *_str++, --_size)
- {
- if ('\0' == match)
- {
- return NULL;
- }
- }
-
- if (0 == _size)
- {
- return NULL;
- }
-
- } while (0 != strncmp(_str, cmp, len) );
-
- return --_str;
- }
-
- /// Find substring in string. Case insensitive.
- inline const char* stristr(const char* _str, const char* _find)
- {
- const char* ptr = _str;
-
- for (size_t len = strlen(_str), searchLen = strlen(_find)
- ; len >= searchLen
- ; ++ptr, --len)
- {
- // Find start of the string.
- while (tolower(*ptr) != tolower(*_find) )
- {
- ++ptr;
- --len;
-
- // Search pattern lenght can't be longer than the string.
- if (searchLen > len)
- {
- return NULL;
- }
- }
-
- // Set pointers.
- const char* string = ptr;
- const char* search = _find;
-
- // Start comparing.
- while (tolower(*string++) == tolower(*search++) )
- {
- // If end of the 'search' string is reached, all characters match.
- if ('\0' == *search)
- {
- return ptr;
- }
- }
- }
-
- return NULL;
- }
+ const char* strnstr(const char* _str, const char* _find, size_t _max = INT32_MAX);
/// Find substring in string. Case insensitive. Limit search to _max.
- inline const char* stristr(const char* _str, const char* _find, size_t _max)
- {
- const char* ptr = _str;
-
- size_t stringLen = strnlen(_str, _max);
- const size_t findLen = strlen(_find);
-
- for (; stringLen >= findLen; ++ptr, --stringLen)
- {
- // Find start of the string.
- while (tolower(*ptr) != tolower(*_find) )
- {
- ++ptr;
- --stringLen;
-
- // Search pattern lenght can't be longer than the string.
- if (findLen > stringLen)
- {
- return NULL;
- }
- }
-
- // Set pointers.
- const char* string = ptr;
- const char* search = _find;
-
- // Start comparing.
- while (tolower(*string++) == tolower(*search++) )
- {
- // If end of the 'search' string is reached, all characters match.
- if ('\0' == *search)
- {
- return ptr;
- }
- }
- }
-
- return NULL;
- }
+ const char* stristr(const char* _str, const char* _find, size_t _max = INT32_MAX);
/// Find new line. Returns pointer after new line terminator.
- inline const char* strnl(const char* _str)
- {
- for (; '\0' != *_str; _str += strnlen(_str, 1024) )
- {
- const char* eol = strnstr(_str, "\r\n", 1024);
- if (NULL != eol)
- {
- return eol + 2;
- }
-
- eol = strnstr(_str, "\n", 1024);
- if (NULL != eol)
- {
- return eol + 1;
- }
- }
-
- return _str;
- }
+ const char* strnl(const char* _str);
/// Find end of line. Retuns pointer to new line terminator.
- inline const char* streol(const char* _str)
- {
- for (; '\0' != *_str; _str += strnlen(_str, 1024) )
- {
- const char* eol = strnstr(_str, "\r\n", 1024);
- if (NULL != eol)
- {
- return eol;
- }
-
- eol = strnstr(_str, "\n", 1024);
- if (NULL != eol)
- {
- return eol;
- }
- }
-
- return _str;
- }
+ const char* streol(const char* _str);
/// Skip whitespace.
- inline const char* strws(const char* _str)
- {
- for (; isspace(*_str); ++_str) {};
- return _str;
- }
+ const char* strws(const char* _str);
/// Skip non-whitespace.
- inline const char* strnws(const char* _str)
- {
- for (; !isspace(*_str); ++_str) {};
- return _str;
- }
+ const char* strnws(const char* _str);
/// Skip word.
- inline const char* strword(const char* _str)
- {
- for (char ch = *_str++; isalnum(ch) || '_' == ch; ch = *_str++) {};
- return _str-1;
- }
+ const char* strword(const char* _str);
/// Find matching block.
- inline const char* strmb(const char* _str, char _open, char _close)
- {
- int count = 0;
- for (char ch = *_str++; ch != '\0' && count >= 0; ch = *_str++)
- {
- if (ch == _open)
- {
- count++;
- }
- else if (ch == _close)
- {
- count--;
- if (0 == count)
- {
- return _str-1;
- }
- }
- }
-
- return NULL;
- }
+ const char* strmb(const char* _str, char _open, char _close);
// Normalize string to sane line endings.
- inline void eolLF(char* _out, size_t _size, const char* _str)
- {
- if (0 < _size)
- {
- char* end = _out + _size - 1;
- for (char ch = *_str++; ch != '\0' && _out < end; ch = *_str++)
- {
- if ('\r' != ch)
- {
- *_out++ = ch;
- }
- }
-
- *_out = '\0';
- }
- }
+ void eolLF(char* _out, size_t _size, const char* _str);
// Finds identifier.
- inline const char* findIdentifierMatch(const char* _str, const char* _word)
- {
- size_t len = strlen(_word);
- const char* ptr = strstr(_str, _word);
- for (; NULL != ptr; ptr = strstr(ptr + len, _word) )
- {
- if (ptr != _str)
- {
- char ch = *(ptr - 1);
- if (isalnum(ch) || '_' == ch)
- {
- continue;
- }
- }
-
- char ch = ptr[len];
- if (isalnum(ch) || '_' == ch)
- {
- continue;
- }
-
- return ptr;
- }
-
- return ptr;
- }
+ const char* findIdentifierMatch(const char* _str, const char* _word);
// Finds any identifier from NULL terminated array of identifiers.
- inline const char* findIdentifierMatch(const char* _str, const char* _words[])
- {
- for (const char* word = *_words; NULL != word; ++_words, word = *_words)
- {
- const char* match = findIdentifierMatch(_str, word);
- if (NULL != match)
- {
- return match;
- }
- }
-
- return NULL;
- }
+ const char* findIdentifierMatch(const char* _str, const char* _words[]);
/// Cross platform implementation of vsnprintf that returns number of
/// characters which would have been written to the final string if
/// enough space had been available.
- inline int32_t vsnprintf(char* _str, size_t _count, const char* _format, va_list _argList)
- {
-#if BX_COMPILER_MSVC
- va_list argListCopy;
- va_copy(argListCopy, _argList);
- int32_t len = ::vsnprintf_s(_str, _count, size_t(-1), _format, argListCopy);
- va_end(argListCopy);
- return -1 == len ? ::_vscprintf(_format, _argList) : len;
-#else
- return ::vsnprintf(_str, _count, _format, _argList);
-#endif // BX_COMPILER_MSVC
- }
+ int32_t vsnprintf(char* _out, size_t _max, const char* _format, va_list _argList);
/// Cross platform implementation of vsnwprintf that returns number of
/// characters which would have been written to the final string if
/// enough space had been available.
- inline int32_t vsnwprintf(wchar_t* _str, size_t _count, const wchar_t* _format, va_list _argList)
- {
-#if BX_COMPILER_MSVC
- va_list argListCopy;
- va_copy(argListCopy, _argList);
- int32_t len = ::_vsnwprintf_s(_str, _count, size_t(-1), _format, argListCopy);
- va_end(argListCopy);
- return -1 == len ? ::_vscwprintf(_format, _argList) : len;
-#elif defined(__MINGW32__)
- return ::vsnwprintf(_str, _count, _format, _argList);
-#else
- return ::vswprintf(_str, _count, _format, _argList);
-#endif // BX_COMPILER_MSVC
- }
+ int32_t vsnwprintf(wchar_t* _out, size_t _max, const wchar_t* _format, va_list _argList);
///
- inline int32_t snprintf(char* _str, size_t _count, const char* _format, ...) // BX_PRINTF_ARGS(3, 4)
- {
- va_list argList;
- va_start(argList, _format);
- int32_t len = vsnprintf(_str, _count, _format, argList);
- va_end(argList);
- return len;
- }
+ int32_t snprintf(char* _out, size_t _max, const char* _format, ...);
///
- inline int32_t swnprintf(wchar_t* _out, size_t _count, const wchar_t* _format, ...)
- {
- va_list argList;
- va_start(argList, _format);
- int32_t len = vsnwprintf(_out, _count, _format, argList);
- va_end(argList);
- return len;
- }
+ int32_t swnprintf(wchar_t* _out, size_t _max, const wchar_t* _format, ...);
///
template <typename Ty>
- inline void stringPrintfVargs(Ty& _out, const char* _format, va_list _argList)
- {
- char temp[2048];
-
- char* out = temp;
- int32_t len = bx::vsnprintf(out, sizeof(temp), _format, _argList);
- if ( (int32_t)sizeof(temp) < len)
- {
- out = (char*)alloca(len+1);
- len = bx::vsnprintf(out, len, _format, _argList);
- }
- out[len] = '\0';
- _out.append(out);
- }
+ void stringPrintfVargs(Ty& _out, const char* _format, va_list _argList);
///
template <typename Ty>
- inline void stringPrintf(Ty& _out, const char* _format, ...)
- {
- va_list argList;
- va_start(argList, _format);
- stringPrintfVargs(_out, _format, argList);
- va_end(argList);
- }
+ void stringPrintf(Ty& _out, const char* _format, ...);
/// Replace all instances of substring.
template <typename Ty>
- inline Ty replaceAll(const Ty& _str, const char* _from, const char* _to)
- {
- Ty str = _str;
- size_t startPos = 0;
- const size_t fromLen = strlen(_from);
- const size_t toLen = strlen(_to);
- while ( (startPos = str.find(_from, startPos) ) != Ty::npos)
- {
- str.replace(startPos, fromLen, _to);
- startPos += toLen;
- }
-
- return str;
- }
+ Ty replaceAll(const Ty& _str, const char* _from, const char* _to);
/// Extract base file name from file path.
- inline const char* baseName(const char* _filePath)
- {
- const char* bs = strrchr(_filePath, '\\');
- const char* fs = strrchr(_filePath, '/');
- const char* slash = (bs > fs ? bs : fs);
- const char* colon = strrchr(_filePath, ':');
- const char* basename = slash > colon ? slash : colon;
- if (NULL != basename)
- {
- return basename+1;
- }
-
- return _filePath;
- }
+ const char* baseName(const char* _filePath);
/// Convert size in bytes to human readable string.
- inline void prettify(char* _out, size_t _count, uint64_t _size)
- {
- uint8_t idx = 0;
- double size = double(_size);
- while (_size != (_size&0x7ff)
- && idx < 9)
- {
- _size >>= 10;
- size *= 1.0/1024.0;
- ++idx;
- }
-
- snprintf(_out, _count, "%0.2f %c%c", size, "BkMGTPEZY"[idx], idx > 0 ? 'B' : '\0');
- }
-
- /*
- * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
+ void prettify(char* _out, size_t _count, uint64_t _size);
/// Copy src to string dst of size siz. At most siz-1 characters
/// will be copied. Always NUL terminates (unless siz == 0).
/// Returns strlen(src); if retval >= siz, truncation occurred.
- inline size_t strlcpy(char* _dst, const char* _src, size_t _siz)
- {
- char* dd = _dst;
- const char* ss = _src;
- size_t nn = _siz;
-
- /* Copy as many bytes as will fit */
- if (nn != 0)
- {
- while (--nn != 0)
- {
- if ( (*dd++ = *ss++) == '\0')
- {
- break;
- }
- }
- }
-
- /* Not enough room in dst, add NUL and traverse rest of src */
- if (nn == 0)
- {
- if (_siz != 0)
- {
- *dd = '\0'; /* NUL-terminate dst */
- }
-
- while (*ss++)
- {
- }
- }
-
- return(ss - _src - 1); /* count does not include NUL */
- }
+ size_t strlcpy(char* _dst, const char* _src, size_t _max);
/// Appends src to string dst of size siz (unlike strncat, siz is the
/// full size of dst, not space left). At most siz-1 characters
/// will be copied. Always NUL terminates (unless siz <= strlen(dst)).
/// Returns strlen(src) + MIN(siz, strlen(initial dst)).
/// If retval >= siz, truncation occurred.
- inline size_t strlcat(char* _dst, const char* _src, size_t _siz)
- {
- char* dd = _dst;
- const char *s = _src;
- size_t nn = _siz;
- size_t dlen;
-
- /* Find the end of dst and adjust bytes left but don't go past end */
- while (nn-- != 0 && *dd != '\0')
- {
- dd++;
- }
-
- dlen = dd - _dst;
- nn = _siz - dlen;
-
- if (nn == 0)
- {
- return(dlen + strlen(s));
- }
-
- while (*s != '\0')
- {
- if (nn != 1)
- {
- *dd++ = *s;
- nn--;
- }
- s++;
- }
- *dd = '\0';
-
- return(dlen + (s - _src)); /* count does not include NUL */
- }
-
- /// Non-zero-terminated string view.
- class StringView
- {
- public:
- StringView()
- {
- clear();
- }
-
- StringView(const StringView& _rhs)
- {
- set(_rhs.m_ptr, _rhs.m_len);
- }
-
- StringView& operator=(const StringView& _rhs)
- {
- set(_rhs.m_ptr, _rhs.m_len);
- return *this;
- }
-
- StringView(const char* _ptr, uint32_t _len = UINT16_MAX)
- {
- set(_ptr, _len);
- }
-
- void set(const char* _ptr, uint32_t _len = UINT16_MAX)
- {
- clear();
-
- if (NULL != _ptr)
- {
- uint32_t len = uint32_t(strnlen(_ptr, _len) );
- if (0 != len)
- {
- m_len = len;
- m_ptr = _ptr;
- }
- }
- }
-
- void clear()
- {
- m_ptr = "";
- m_len = 0;
- }
-
- const char* getPtr() const
- {
- return m_ptr;
- }
-
- const char* getTerm() const
- {
- return m_ptr + m_len;
- }
-
- bool isEmpty() const
- {
- return 0 == m_len;
- }
-
- uint32_t getLength() const
- {
- return m_len;
- }
+ size_t strlcat(char* _dst, const char* _src, size_t _max);
- protected:
- friend uint32_t hashMurmur2A(const StringView& _data);
+ ///
+ int32_t toString(char* _out, size_t _max, double _value);
- const char* m_ptr;
- uint32_t m_len;
- };
+ ///
+ int32_t toString(char* _out, size_t _max, int32_t _value, uint32_t _base = 10);
- inline uint32_t hashMurmur2A(const StringView& _data)
- {
- return hashMurmur2A(_data.m_ptr, _data.m_len);
- }
+ ///
+ int32_t toString(char* _out, size_t _max, uint32_t _value, uint32_t _base = 10);
- inline uint32_t hashMurmur2A(const char* _data)
- {
- return hashMurmur2A(StringView(_data) );
- }
+ ///
+ uint32_t hashMurmur2A(const StringView& _data);
- /// ASCII string
- template<bx::AllocatorI** AllocatorT>
- class StringT : public StringView
- {
- public:
- StringT()
- : StringView()
- {
- }
-
- StringT(const StringT<AllocatorT>& _rhs)
- : StringView()
- {
- set(_rhs.m_ptr, _rhs.m_len);
- }
-
- StringT<AllocatorT>& operator=(const StringT<AllocatorT>& _rhs)
- {
- set(_rhs.m_ptr, _rhs.m_len);
- return *this;
- }
-
- StringT(const char* _ptr, uint32_t _len = UINT32_MAX)
- {
- set(_ptr, _len);
- }
-
- StringT(const StringView& _rhs)
- {
- set(_rhs.getPtr(), _rhs.getLength() );
- }
-
- ~StringT()
- {
- clear();
- }
-
- void set(const char* _ptr, uint32_t _len = UINT32_MAX)
- {
- clear();
- append(_ptr, _len);
- }
-
- void append(const char* _ptr, uint32_t _len = UINT32_MAX)
- {
- if (0 != _len)
- {
- uint32_t old = m_len;
- uint32_t len = m_len + uint32_t(strnlen(_ptr, _len) );
- char* ptr = (char*)BX_REALLOC(*AllocatorT, 0 != m_len ? const_cast<char*>(m_ptr) : NULL, len+1);
- m_len = len;
- strlncpy(ptr + old, len-old+1, _ptr, _len);
-
- *const_cast<char**>(&m_ptr) = ptr;
- }
- }
-
- void clear()
- {
- if (0 != m_len)
- {
- BX_FREE(*AllocatorT, const_cast<char*>(m_ptr) );
-
- StringView::clear();
- }
- }
- };
+ ///
+ uint32_t hashMurmur2A(const char* _data);
} // namespace bx
+#include "string.inl"
+
#endif // BX_STRING_H_HEADER_GUARD
diff --git a/3rdparty/bx/include/bx/string.inl b/3rdparty/bx/include/bx/string.inl
new file mode 100644
index 00000000000..42f2a6a05b9
--- /dev/null
+++ b/3rdparty/bx/include/bx/string.inl
@@ -0,0 +1,200 @@
+/*
+ * Copyright 2010-2017 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ */
+
+#ifndef BX_STRING_H_HEADER_GUARD
+# error "Must be included from bx/string.h!"
+#endif // BX_STRING_H_HEADER_GUARD
+
+#if BX_CRT_MSVC && !defined(va_copy)
+# define va_copy(_a, _b) (_a) = (_b)
+#endif // BX_CRT_MSVC && !defined(va_copy)
+
+namespace bx
+{
+ template <typename Ty>
+ inline void stringPrintfVargs(Ty& _out, const char* _format, va_list _argList)
+ {
+ char temp[2048];
+
+ char* out = temp;
+ int32_t len = bx::vsnprintf(out, sizeof(temp), _format, _argList);
+ if ( (int32_t)sizeof(temp) < len)
+ {
+ out = (char*)alloca(len+1);
+ len = bx::vsnprintf(out, len, _format, _argList);
+ }
+ out[len] = '\0';
+ _out.append(out);
+ }
+
+ template <typename Ty>
+ inline void stringPrintf(Ty& _out, const char* _format, ...)
+ {
+ va_list argList;
+ va_start(argList, _format);
+ stringPrintfVargs(_out, _format, argList);
+ va_end(argList);
+ }
+
+ template <typename Ty>
+ inline Ty replaceAll(const Ty& _str, const char* _from, const char* _to)
+ {
+ Ty str = _str;
+ size_t startPos = 0;
+ const size_t fromLen = strlen(_from);
+ const size_t toLen = strlen(_to);
+ while ( (startPos = str.find(_from, startPos) ) != Ty::npos)
+ {
+ str.replace(startPos, fromLen, _to);
+ startPos += toLen;
+ }
+
+ return str;
+ }
+
+ inline StringView::StringView()
+ {
+ clear();
+ }
+
+ inline StringView::StringView(const StringView& _rhs)
+ {
+ set(_rhs.m_ptr, _rhs.m_len);
+ }
+
+ inline StringView& StringView::operator=(const StringView& _rhs)
+ {
+ set(_rhs.m_ptr, _rhs.m_len);
+ return *this;
+ }
+
+ inline StringView::StringView(const char* _ptr, uint32_t _len)
+ {
+ set(_ptr, _len);
+ }
+
+ inline void StringView::set(const char* _ptr, uint32_t _len)
+ {
+ clear();
+
+ if (NULL != _ptr)
+ {
+ uint32_t len = uint32_t(strnlen(_ptr, _len) );
+ if (0 != len)
+ {
+ m_len = len;
+ m_ptr = _ptr;
+ }
+ }
+ }
+
+ inline void StringView::clear()
+ {
+ m_ptr = "";
+ m_len = 0;
+ }
+
+ inline const char* StringView::getPtr() const
+ {
+ return m_ptr;
+ }
+
+ inline const char* StringView::getTerm() const
+ {
+ return m_ptr + m_len;
+ }
+
+ inline bool StringView::isEmpty() const
+ {
+ return 0 == m_len;
+ }
+
+ inline uint32_t StringView::getLength() const
+ {
+ return m_len;
+ }
+
+ inline uint32_t hashMurmur2A(const StringView& _data)
+ {
+ return hashMurmur2A(_data.getPtr(), _data.getLength() );
+ }
+
+ inline uint32_t hashMurmur2A(const char* _data)
+ {
+ return hashMurmur2A(StringView(_data) );
+ }
+
+ template<bx::AllocatorI** AllocatorT>
+ inline StringT<AllocatorT>::StringT()
+ : StringView()
+ {
+ }
+
+ template<bx::AllocatorI** AllocatorT>
+ inline StringT<AllocatorT>::StringT(const StringT<AllocatorT>& _rhs)
+ : StringView()
+ {
+ set(_rhs.m_ptr, _rhs.m_len);
+ }
+
+ template<bx::AllocatorI** AllocatorT>
+ inline StringT<AllocatorT>& StringT<AllocatorT>::operator=(const StringT<AllocatorT>& _rhs)
+ {
+ set(_rhs.m_ptr, _rhs.m_len);
+ return *this;
+ }
+
+ template<bx::AllocatorI** AllocatorT>
+ inline StringT<AllocatorT>::StringT(const char* _ptr, uint32_t _len)
+ {
+ set(_ptr, _len);
+ }
+
+ template<bx::AllocatorI** AllocatorT>
+ inline StringT<AllocatorT>::StringT(const StringView& _rhs)
+ {
+ set(_rhs.getPtr(), _rhs.getLength() );
+ }
+
+ template<bx::AllocatorI** AllocatorT>
+ inline StringT<AllocatorT>::~StringT()
+ {
+ clear();
+ }
+
+ template<bx::AllocatorI** AllocatorT>
+ inline void StringT<AllocatorT>::set(const char* _ptr, uint32_t _len)
+ {
+ clear();
+ append(_ptr, _len);
+ }
+
+ template<bx::AllocatorI** AllocatorT>
+ inline void StringT<AllocatorT>::append(const char* _ptr, uint32_t _len)
+ {
+ if (0 != _len)
+ {
+ uint32_t old = m_len;
+ uint32_t len = m_len + uint32_t(strnlen(_ptr, _len) );
+ char* ptr = (char*)BX_REALLOC(*AllocatorT, 0 != m_len ? const_cast<char*>(m_ptr) : NULL, len+1);
+ m_len = len;
+ strlncpy(ptr + old, len-old+1, _ptr, _len);
+
+ *const_cast<char**>(&m_ptr) = ptr;
+ }
+ }
+
+ template<bx::AllocatorI** AllocatorT>
+ inline void StringT<AllocatorT>::clear()
+ {
+ if (0 != m_len)
+ {
+ BX_FREE(*AllocatorT, const_cast<char*>(m_ptr) );
+
+ StringView::clear();
+ }
+ }
+
+} // namespace bx
diff --git a/3rdparty/bx/include/bx/thread.h b/3rdparty/bx/include/bx/thread.h
index 8514a704280..95152367f02 100644
--- a/3rdparty/bx/include/bx/thread.h
+++ b/3rdparty/bx/include/bx/thread.h
@@ -6,6 +6,8 @@
#ifndef BX_THREAD_H_HEADER_GUARD
#define BX_THREAD_H_HEADER_GUARD
+#include "bx.h"
+
#if BX_PLATFORM_POSIX
# include <pthread.h>
# if defined(__FreeBSD__)
@@ -26,8 +28,10 @@ using namespace Windows::System::Threading;
namespace bx
{
+ ///
typedef int32_t (*ThreadFn)(void* _userData);
+ ///
class Thread
{
BX_CLASS(Thread
@@ -36,205 +40,36 @@ namespace bx
);
public:
- Thread()
-#if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 || BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT
- : m_handle(INVALID_HANDLE_VALUE)
- , m_threadId(UINT32_MAX)
-#elif BX_PLATFORM_POSIX
- : m_handle(0)
-#endif // BX_PLATFORM_
- , m_fn(NULL)
- , m_userData(NULL)
- , m_stackSize(0)
- , m_exitCode(0 /*EXIT_SUCCESS*/)
- , m_running(false)
- {
- }
+ ///
+ Thread();
- virtual ~Thread()
- {
- if (m_running)
- {
- shutdown();
- }
- }
+ ///
+ virtual ~Thread();
- void init(ThreadFn _fn, void* _userData = NULL, uint32_t _stackSize = 0, const char* _name = NULL)
- {
- BX_CHECK(!m_running, "Already running!");
+ ///
+ void init(ThreadFn _fn, void* _userData = NULL, uint32_t _stackSize = 0, const char* _name = NULL);
- m_fn = _fn;
- m_userData = _userData;
- m_stackSize = _stackSize;
- m_running = true;
+ ///
+ void shutdown();
-#if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 || BX_PLATFORM_XBOXONE
- m_handle = ::CreateThread(NULL
- , m_stackSize
- , (LPTHREAD_START_ROUTINE)threadFunc
- , this
- , 0
- , NULL
- );
-#elif BX_PLATFORM_WINRT
- m_handle = CreateEventEx(nullptr, nullptr, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS);
- auto workItemHandler = ref new WorkItemHandler([=](IAsyncAction^)
- {
- m_exitCode = threadFunc(this);
- SetEvent(m_handle);
- }, CallbackContext::Any);
+ ///
+ bool isRunning() const;
- ThreadPool::RunAsync(workItemHandler, WorkItemPriority::Normal, WorkItemOptions::TimeSliced);
-#elif BX_PLATFORM_POSIX
- int result;
- BX_UNUSED(result);
-
- pthread_attr_t attr;
- result = pthread_attr_init(&attr);
- BX_CHECK(0 == result, "pthread_attr_init failed! %d", result);
-
- if (0 != m_stackSize)
- {
- result = pthread_attr_setstacksize(&attr, m_stackSize);
- BX_CHECK(0 == result, "pthread_attr_setstacksize failed! %d", result);
- }
-
-// sched_param sched;
-// sched.sched_priority = 0;
-// result = pthread_attr_setschedparam(&attr, &sched);
-// BX_CHECK(0 == result, "pthread_attr_setschedparam failed! %d", result);
-
- result = pthread_create(&m_handle, &attr, &threadFunc, this);
- BX_CHECK(0 == result, "pthread_attr_setschedparam failed! %d", result);
-#else
-# error "Not implemented!"
-#endif // BX_PLATFORM_
+ ///
+ int32_t getExitCode() const;
- m_sem.wait();
-
- if (NULL != _name)
- {
- setThreadName(_name);
- }
- }
-
- void shutdown()
- {
- BX_CHECK(m_running, "Not running!");
-#if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360
- WaitForSingleObject(m_handle, INFINITE);
- GetExitCodeThread(m_handle, (DWORD*)&m_exitCode);
- CloseHandle(m_handle);
- m_handle = INVALID_HANDLE_VALUE;
-#elif BX_PLATFORM_WINRT
- WaitForSingleObjectEx(m_handle, INFINITE, FALSE);
- CloseHandle(m_handle);
- m_handle = INVALID_HANDLE_VALUE;
-#elif BX_PLATFORM_POSIX
- union
- {
- void* ptr;
- int32_t i;
- } cast;
- pthread_join(m_handle, &cast.ptr);
- m_exitCode = cast.i;
- m_handle = 0;
-#endif // BX_PLATFORM_
- m_running = false;
- }
-
- bool isRunning() const
- {
- return m_running;
- }
-
- int32_t getExitCode() const
- {
- return m_exitCode;
- }
-
- void setThreadName(const char* _name)
- {
-#if BX_PLATFORM_OSX || BX_PLATFORM_IOS
- pthread_setname_np(_name);
-#elif (BX_CRT_GLIBC >= 21200) && ! BX_PLATFORM_HURD
- pthread_setname_np(m_handle, _name);
-#elif BX_PLATFORM_LINUX
- prctl(PR_SET_NAME,_name, 0, 0, 0);
-#elif BX_PLATFORM_BSD
-# ifdef __NetBSD__
- pthread_setname_np(m_handle, "%s", (void*)_name);
-# else
- pthread_set_name_np(m_handle, _name);
-# endif // __NetBSD__
-#elif BX_PLATFORM_WINDOWS && BX_COMPILER_MSVC
-# pragma pack(push, 8)
- struct ThreadName
- {
- DWORD type;
- LPCSTR name;
- DWORD id;
- DWORD flags;
- };
-# pragma pack(pop)
- ThreadName tn;
- tn.type = 0x1000;
- tn.name = _name;
- tn.id = m_threadId;
- tn.flags = 0;
-
- __try
- {
- RaiseException(0x406d1388
- , 0
- , sizeof(tn)/4
- , reinterpret_cast<ULONG_PTR*>(&tn)
- );
- }
- __except(EXCEPTION_EXECUTE_HANDLER)
- {
- }
-#else
- BX_UNUSED(_name);
-#endif // BX_PLATFORM_
- }
+ ///
+ void setThreadName(const char* _name);
private:
- int32_t entry()
- {
-#if BX_PLATFORM_WINDOWS
- m_threadId = ::GetCurrentThreadId();
-#endif // BX_PLATFORM_WINDOWS
-
- m_sem.post();
- return m_fn(m_userData);
- }
-
-#if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 || BX_PLATFORM_WINRT
- static DWORD WINAPI threadFunc(LPVOID _arg)
- {
- Thread* thread = (Thread*)_arg;
- int32_t result = thread->entry();
- return result;
- }
-#else
- static void* threadFunc(void* _arg)
- {
- Thread* thread = (Thread*)_arg;
- union
- {
- void* ptr;
- int32_t i;
- } cast;
- cast.i = thread->entry();
- return cast.ptr;
- }
-#endif // BX_PLATFORM_
+ int32_t entry();
#if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 || BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT
+ static DWORD WINAPI threadFunc(LPVOID _arg);
HANDLE m_handle;
DWORD m_threadId;
#elif BX_PLATFORM_POSIX
+ static void* threadFunc(void* _arg);
pthread_t m_handle;
#endif // BX_PLATFORM_
@@ -246,71 +81,34 @@ namespace bx
bool m_running;
};
-#if BX_PLATFORM_WINDOWS
+ ///
class TlsData
{
public:
- TlsData()
- {
- m_id = TlsAlloc();
- BX_CHECK(TLS_OUT_OF_INDEXES != m_id, "Failed to allocated TLS index (err: 0x%08x).", GetLastError() );
- }
+ ///
+ TlsData();
- ~TlsData()
- {
- BOOL result = TlsFree(m_id);
- BX_CHECK(0 != result, "Failed to free TLS index (err: 0x%08x).", GetLastError() ); BX_UNUSED(result);
- }
+ ///
+ ~TlsData();
- void* get() const
- {
- return TlsGetValue(m_id);
- }
+ ///
+ void* get() const;
- void set(void* _ptr)
- {
- TlsSetValue(m_id, _ptr);
- }
+ ///
+ void set(void* _ptr);
private:
+#if BX_PLATFORM_WINDOWS
uint32_t m_id;
- };
-
#elif !(BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT)
-
- class TlsData
- {
- public:
- TlsData()
- {
- int result = pthread_key_create(&m_id, NULL);
- BX_CHECK(0 == result, "pthread_key_create failed %d.", result); BX_UNUSED(result);
- }
-
- ~TlsData()
- {
- int result = pthread_key_delete(m_id);
- BX_CHECK(0 == result, "pthread_key_delete failed %d.", result); BX_UNUSED(result);
- }
-
- void* get() const
- {
- return pthread_getspecific(m_id);
- }
-
- void set(void* _ptr)
- {
- int result = pthread_setspecific(m_id, _ptr);
- BX_CHECK(0 == result, "pthread_setspecific failed %d.", result); BX_UNUSED(result);
- }
-
- private:
pthread_key_t m_id;
- };
#endif // BX_PLATFORM_*
+ };
} // namespace bx
#endif // BX_CONFIG_SUPPORTS_THREADING
+#include "thread.inl"
+
#endif // BX_THREAD_H_HEADER_GUARD
diff --git a/3rdparty/bx/include/bx/thread.inl b/3rdparty/bx/include/bx/thread.inl
new file mode 100644
index 00000000000..38fc49d0c3a
--- /dev/null
+++ b/3rdparty/bx/include/bx/thread.inl
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2010-2017 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ */
+
+#ifndef BX_THREAD_H_HEADER_GUARD
+# error "Must be included from bx/thread.h!"
+#endif // BX_THREAD_H_HEADER_GUARD
+
+#if BX_CONFIG_SUPPORTS_THREADING
+
+namespace bx
+{
+#if BX_PLATFORM_WINDOWS
+ inline TlsData::TlsData()
+ {
+ m_id = TlsAlloc();
+ BX_CHECK(TLS_OUT_OF_INDEXES != m_id, "Failed to allocated TLS index (err: 0x%08x).", GetLastError() );
+ }
+
+ inline TlsData::~TlsData()
+ {
+ BOOL result = TlsFree(m_id);
+ BX_CHECK(0 != result, "Failed to free TLS index (err: 0x%08x).", GetLastError() ); BX_UNUSED(result);
+ }
+
+ inline void* TlsData::get() const
+ {
+ return TlsGetValue(m_id);
+ }
+
+ inline void TlsData::set(void* _ptr)
+ {
+ TlsSetValue(m_id, _ptr);
+ }
+
+#elif !(BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT)
+
+ inline TlsData::TlsData()
+ {
+ int result = pthread_key_create(&m_id, NULL);
+ BX_CHECK(0 == result, "pthread_key_create failed %d.", result); BX_UNUSED(result);
+ }
+
+ inline TlsData::~TlsData()
+ {
+ int result = pthread_key_delete(m_id);
+ BX_CHECK(0 == result, "pthread_key_delete failed %d.", result); BX_UNUSED(result);
+ }
+
+ inline void* TlsData::get() const
+ {
+ return pthread_getspecific(m_id);
+ }
+
+ inline void TlsData::set(void* _ptr)
+ {
+ int result = pthread_setspecific(m_id, _ptr);
+ BX_CHECK(0 == result, "pthread_setspecific failed %d.", result); BX_UNUSED(result);
+ }
+#endif // BX_PLATFORM_*
+
+} // namespace bx
+
+#endif // BX_CONFIG_SUPPORTS_THREADING
diff --git a/3rdparty/bx/include/bx/timer.h b/3rdparty/bx/include/bx/timer.h
index 622e184e968..7b01e2c9974 100644
--- a/3rdparty/bx/include/bx/timer.h
+++ b/3rdparty/bx/include/bx/timer.h
@@ -8,55 +8,16 @@
#include "bx.h"
-#if BX_PLATFORM_ANDROID
-# include <time.h> // clock, clock_gettime
-#elif BX_PLATFORM_EMSCRIPTEN
-# include <emscripten.h>
-#elif BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT
-# include <windows.h>
-#else
-# include <sys/time.h> // gettimeofday
-#endif // BX_PLATFORM_
-
namespace bx
{
- inline int64_t getHPCounter()
- {
-#if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 || BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT
- LARGE_INTEGER li;
- // Performance counter value may unexpectedly leap forward
- // http://support.microsoft.com/kb/274323
- QueryPerformanceCounter(&li);
- int64_t i64 = li.QuadPart;
-#elif BX_PLATFORM_ANDROID
- struct timespec now;
- clock_gettime(CLOCK_MONOTONIC, &now);
- int64_t i64 = now.tv_sec*INT64_C(1000000000) + now.tv_nsec;
-#elif BX_PLATFORM_EMSCRIPTEN
- int64_t i64 = int64_t(1000.0f * emscripten_get_now() );
-#else
- struct timeval now;
- gettimeofday(&now, 0);
- int64_t i64 = now.tv_sec*INT64_C(1000000) + now.tv_usec;
-#endif // BX_PLATFORM_
- return i64;
- }
+ ///
+ int64_t getHPCounter();
- inline int64_t getHPFrequency()
- {
-#if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 || BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT
- LARGE_INTEGER li;
- QueryPerformanceFrequency(&li);
- return li.QuadPart;
-#elif BX_PLATFORM_ANDROID
- return INT64_C(1000000000);
-#elif BX_PLATFORM_EMSCRIPTEN
- return INT64_C(1000000);
-#else
- return INT64_C(1000000);
-#endif // BX_PLATFORM_
- }
+ ///
+ int64_t getHPFrequency();
} // namespace bx
+#include "timer.inl"
+
#endif // BX_TIMER_H_HEADER_GUARD
diff --git a/3rdparty/bx/include/bx/timer.inl b/3rdparty/bx/include/bx/timer.inl
new file mode 100644
index 00000000000..d1c609f571a
--- /dev/null
+++ b/3rdparty/bx/include/bx/timer.inl
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2010-2017 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ */
+
+#ifndef BX_TIMER_H_HEADER_GUARD
+# error "Must be included from bx/timer.h!"
+#endif // BX_TIMER_H_HEADER_GUARD
+
+#include "bx.h"
+
+#if BX_PLATFORM_ANDROID
+# include <time.h> // clock, clock_gettime
+#elif BX_PLATFORM_EMSCRIPTEN
+# include <emscripten.h>
+#elif BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT
+# include <windows.h>
+#else
+# include <sys/time.h> // gettimeofday
+#endif // BX_PLATFORM_
+
+namespace bx
+{
+ inline int64_t getHPCounter()
+ {
+#if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 || BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT
+ LARGE_INTEGER li;
+ // Performance counter value may unexpectedly leap forward
+ // http://support.microsoft.com/kb/274323
+ QueryPerformanceCounter(&li);
+ int64_t i64 = li.QuadPart;
+#elif BX_PLATFORM_ANDROID
+ struct timespec now;
+ clock_gettime(CLOCK_MONOTONIC, &now);
+ int64_t i64 = now.tv_sec*INT64_C(1000000000) + now.tv_nsec;
+#elif BX_PLATFORM_EMSCRIPTEN
+ int64_t i64 = int64_t(1000.0f * emscripten_get_now() );
+#else
+ struct timeval now;
+ gettimeofday(&now, 0);
+ int64_t i64 = now.tv_sec*INT64_C(1000000) + now.tv_usec;
+#endif // BX_PLATFORM_
+ return i64;
+ }
+
+ inline int64_t getHPFrequency()
+ {
+#if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 || BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT
+ LARGE_INTEGER li;
+ QueryPerformanceFrequency(&li);
+ return li.QuadPart;
+#elif BX_PLATFORM_ANDROID
+ return INT64_C(1000000000);
+#elif BX_PLATFORM_EMSCRIPTEN
+ return INT64_C(1000000);
+#else
+ return INT64_C(1000000);
+#endif // BX_PLATFORM_
+ }
+
+} // namespace bx
diff --git a/3rdparty/bx/include/bx/tokenizecmd.h b/3rdparty/bx/include/bx/tokenizecmd.h
deleted file mode 100644
index 0fe2e00b67a..00000000000
--- a/3rdparty/bx/include/bx/tokenizecmd.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright 2012-2017 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
- */
-
-#ifndef BX_TOKENIZE_CMD_H_HEADER_GUARD
-#define BX_TOKENIZE_CMD_H_HEADER_GUARD
-
-#include <stdint.h>
-#include <stdio.h>
-#include <ctype.h>
-
-namespace bx
-{
- // Reference:
- // http://msdn.microsoft.com/en-us/library/a1y7w461.aspx
- static inline const char* tokenizeCommandLine(const char* _commandLine, char* _buffer, uint32_t& _bufferSize, int& _argc, char* _argv[], int _maxArgvs, char _term = '\0')
- {
- int argc = 0;
- const char* curr = _commandLine;
- char* currOut = _buffer;
- char term = ' ';
- bool sub = false;
-
- enum ParserState
- {
- SkipWhitespace,
- SetTerm,
- Copy,
- Escape,
- End,
- };
-
- ParserState state = SkipWhitespace;
-
- while ('\0' != *curr
- && _term != *curr
- && argc < _maxArgvs)
- {
- switch (state)
- {
- case SkipWhitespace:
- for (; isspace(*curr); ++curr) {}; // skip whitespace
- state = SetTerm;
- break;
-
- case SetTerm:
- if ('"' == *curr)
- {
- term = '"';
- ++curr; // skip begining quote
- }
- else
- {
- term = ' ';
- }
-
- _argv[argc] = currOut;
- ++argc;
-
- state = Copy;
- break;
-
- case Copy:
- if ('\\' == *curr)
- {
- state = Escape;
- }
- else if ('"' == *curr
- && '"' != term)
- {
- sub = !sub;
- }
- else if (isspace(*curr) && !sub)
- {
- state = End;
- }
- else if (term != *curr || sub)
- {
- *currOut = *curr;
- ++currOut;
- }
- else
- {
- state = End;
- }
- ++curr;
- break;
-
- case Escape:
- {
- const char* start = --curr;
- for (; '\\' == *curr; ++curr) {};
-
- if ('"' != *curr)
- {
- int count = (int)(curr-start);
-
- curr = start;
- for (int ii = 0; ii < count; ++ii)
- {
- *currOut = *curr;
- ++currOut;
- ++curr;
- }
- }
- else
- {
- curr = start+1;
- *currOut = *curr;
- ++currOut;
- ++curr;
- }
- }
- state = Copy;
- break;
-
- case End:
- *currOut = '\0';
- ++currOut;
- state = SkipWhitespace;
- break;
- }
- }
-
- *currOut = '\0';
- if (0 < argc
- && '\0' == _argv[argc-1][0])
- {
- --argc;
- }
-
- _bufferSize = (uint32_t)(currOut - _buffer);
- _argc = argc;
-
- if ('\0' != *curr)
- {
- ++curr;
- }
-
- return curr;
- }
-
-} // namespace bx
-
-#endif // TOKENIZE_CMD_H_HEADER_GUARD
diff --git a/3rdparty/bx/include/bx/uint32_t.h b/3rdparty/bx/include/bx/uint32_t.h
index a7d6c45ad90..d3b3069fe92 100644
--- a/3rdparty/bx/include/bx/uint32_t.h
+++ b/3rdparty/bx/include/bx/uint32_t.h
@@ -3,26 +3,6 @@
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
-// Copyright 2006 Mike Acton <macton@gmail.com>
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the "Software"),
-// to deal in the Software without restriction, including without limitation
-// the rights to use, copy, modify, merge, publish, distribute, sublicense,
-// and/or sell copies of the Software, and to permit persons to whom the
-// Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE
-
#ifndef BX_UINT32_T_H_HEADER_GUARD
#define BX_UINT32_T_H_HEADER_GUARD
@@ -30,9 +10,6 @@
#if BX_COMPILER_MSVC
# if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT
-# include <math.h> // math.h is included because VS bitches:
- // warning C4985: 'ceil': attributes not present on previous declaration.
- // must be included before intrin.h.
# include <intrin.h>
# pragma intrinsic(_BitScanForward)
# pragma intrinsic(_BitScanReverse)
@@ -50,756 +27,264 @@
namespace bx
{
- inline uint32_t uint32_li(uint32_t _a)
- {
- return _a;
- }
-
- inline uint32_t uint32_dec(uint32_t _a)
- {
- return _a - 1;
- }
-
- inline uint32_t uint32_inc(uint32_t _a)
- {
- return _a + 1;
- }
-
- inline uint32_t uint32_not(uint32_t _a)
- {
- return ~_a;
- }
-
- inline uint32_t uint32_neg(uint32_t _a)
- {
- return -(int32_t)_a;
- }
-
- inline uint32_t uint32_ext(uint32_t _a)
- {
- return ( (int32_t)_a)>>31;
- }
-
- inline uint32_t uint32_and(uint32_t _a, uint32_t _b)
- {
- return _a & _b;
- }
-
- inline uint32_t uint32_andc(uint32_t _a, uint32_t _b)
- {
- return _a & ~_b;
- }
-
- inline uint32_t uint32_xor(uint32_t _a, uint32_t _b)
- {
- return _a ^ _b;
- }
-
- inline uint32_t uint32_xorl(uint32_t _a, uint32_t _b)
- {
- return !_a != !_b;
- }
-
- inline uint32_t uint32_or(uint32_t _a, uint32_t _b)
- {
- return _a | _b;
- }
-
- inline uint32_t uint32_orc(uint32_t _a, uint32_t _b)
- {
- return _a | ~_b;
- }
-
- inline uint32_t uint32_sll(uint32_t _a, int _sa)
- {
- return _a << _sa;
- }
-
- inline uint32_t uint32_srl(uint32_t _a, int _sa)
- {
- return _a >> _sa;
- }
-
- inline uint32_t uint32_sra(uint32_t _a, int _sa)
- {
- return ( (int32_t)_a) >> _sa;
- }
-
- inline uint32_t uint32_rol(uint32_t _a, int _sa)
- {
- return ( _a << _sa) | (_a >> (32-_sa) );
- }
-
- inline uint32_t uint32_ror(uint32_t _a, int _sa)
- {
- return ( _a >> _sa) | (_a << (32-_sa) );
- }
-
- inline uint32_t uint32_add(uint32_t _a, uint32_t _b)
- {
- return _a + _b;
- }
-
- inline uint32_t uint32_sub(uint32_t _a, uint32_t _b)
- {
- return _a - _b;
- }
-
- inline uint32_t uint32_mul(uint32_t _a, uint32_t _b)
- {
- return _a * _b;
- }
-
- inline uint32_t uint32_div(uint32_t _a, uint32_t _b)
- {
- return (_a / _b);
- }
-
- inline uint32_t uint32_mod(uint32_t _a, uint32_t _b)
- {
- return (_a % _b);
- }
-
- inline uint32_t uint32_cmpeq(uint32_t _a, uint32_t _b)
- {
- return -(_a == _b);
- }
-
- inline uint32_t uint32_cmpneq(uint32_t _a, uint32_t _b)
- {
- return -(_a != _b);
- }
-
- inline uint32_t uint32_cmplt(uint32_t _a, uint32_t _b)
- {
- return -(_a < _b);
- }
-
- inline uint32_t uint32_cmple(uint32_t _a, uint32_t _b)
- {
- return -(_a <= _b);
- }
-
- inline uint32_t uint32_cmpgt(uint32_t _a, uint32_t _b)
- {
- return -(_a > _b);
- }
-
- inline uint32_t uint32_cmpge(uint32_t _a, uint32_t _b)
- {
- return -(_a >= _b);
- }
-
- inline uint32_t uint32_setnz(uint32_t _a)
- {
- return -!!_a;
- }
-
- inline uint32_t uint32_satadd(uint32_t _a, uint32_t _b)
- {
- const uint32_t add = uint32_add(_a, _b);
- const uint32_t lt = uint32_cmplt(add, _a);
- const uint32_t result = uint32_or(add, lt);
-
- return result;
- }
-
- inline uint32_t uint32_satsub(uint32_t _a, uint32_t _b)
- {
- const uint32_t sub = uint32_sub(_a, _b);
- const uint32_t le = uint32_cmple(sub, _a);
- const uint32_t result = uint32_and(sub, le);
-
- return result;
- }
-
- inline uint32_t uint32_satmul(uint32_t _a, uint32_t _b)
- {
- const uint64_t mul = (uint64_t)_a * (uint64_t)_b;
- const uint32_t hi = mul >> 32;
- const uint32_t nz = uint32_setnz(hi);
- const uint32_t result = uint32_or(uint32_t(mul), nz);
-
- return result;
- }
-
- inline uint32_t uint32_sels(uint32_t test, uint32_t _a, uint32_t _b)
- {
- const uint32_t mask = uint32_ext(test);
- const uint32_t sel_a = uint32_and(_a, mask);
- const uint32_t sel_b = uint32_andc(_b, mask);
- const uint32_t result = uint32_or(sel_a, sel_b);
-
- return (result);
- }
-
- inline uint32_t uint32_selb(uint32_t _mask, uint32_t _a, uint32_t _b)
- {
- const uint32_t sel_a = uint32_and(_a, _mask);
- const uint32_t sel_b = uint32_andc(_b, _mask);
- const uint32_t result = uint32_or(sel_a, sel_b);
-
- return (result);
- }
-
- inline uint32_t uint32_imin(uint32_t _a, uint32_t _b)
- {
- const uint32_t a_sub_b = uint32_sub(_a, _b);
- const uint32_t result = uint32_sels(a_sub_b, _a, _b);
-
- return result;
- }
-
- inline uint32_t uint32_imax(uint32_t _a, uint32_t _b)
- {
- const uint32_t b_sub_a = uint32_sub(_b, _a);
- const uint32_t result = uint32_sels(b_sub_a, _a, _b);
-
- return result;
- }
-
- inline uint32_t uint32_min(uint32_t _a, uint32_t _b)
- {
- return _a > _b ? _b : _a;
- }
-
- inline uint32_t uint32_min(uint32_t _a, uint32_t _b, uint32_t _c)
- {
- return uint32_min(_a, uint32_min(_b, _c) );
- }
-
- inline uint32_t uint32_max(uint32_t _a, uint32_t _b)
- {
- return _a > _b ? _a : _b;
- }
-
- inline uint32_t uint32_max(uint32_t _a, uint32_t _b, uint32_t _c)
- {
- return uint32_max(_a, uint32_max(_b, _c) );
- }
-
- inline uint32_t uint32_clamp(uint32_t _a, uint32_t _min, uint32_t _max)
- {
- const uint32_t tmp = uint32_max(_a, _min);
- const uint32_t result = uint32_min(tmp, _max);
-
- return result;
- }
-
- inline uint32_t uint32_iclamp(uint32_t _a, uint32_t _min, uint32_t _max)
- {
- const uint32_t tmp = uint32_imax(_a, _min);
- const uint32_t result = uint32_imin(tmp, _max);
-
- return result;
- }
-
- inline uint32_t uint32_incwrap(uint32_t _val, uint32_t _min, uint32_t _max)
- {
- const uint32_t inc = uint32_inc(_val);
- const uint32_t max_diff = uint32_sub(_max, _val);
- const uint32_t neg_max_diff = uint32_neg(max_diff);
- const uint32_t max_or = uint32_or(max_diff, neg_max_diff);
- const uint32_t max_diff_nz = uint32_ext(max_or);
- const uint32_t result = uint32_selb(max_diff_nz, inc, _min);
-
- return result;
- }
-
- inline uint32_t uint32_decwrap(uint32_t _val, uint32_t _min, uint32_t _max)
- {
- const uint32_t dec = uint32_dec(_val);
- const uint32_t min_diff = uint32_sub(_min, _val);
- const uint32_t neg_min_diff = uint32_neg(min_diff);
- const uint32_t min_or = uint32_or(min_diff, neg_min_diff);
- const uint32_t min_diff_nz = uint32_ext(min_or);
- const uint32_t result = uint32_selb(min_diff_nz, dec, _max);
-
- return result;
- }
-
- inline uint32_t uint32_cntbits_ref(uint32_t _val)
- {
- const uint32_t tmp0 = uint32_srl(_val, 1);
- const uint32_t tmp1 = uint32_and(tmp0, 0x55555555);
- const uint32_t tmp2 = uint32_sub(_val, tmp1);
- const uint32_t tmp3 = uint32_and(tmp2, 0xc30c30c3);
- const uint32_t tmp4 = uint32_srl(tmp2, 2);
- const uint32_t tmp5 = uint32_and(tmp4, 0xc30c30c3);
- const uint32_t tmp6 = uint32_srl(tmp2, 4);
- const uint32_t tmp7 = uint32_and(tmp6, 0xc30c30c3);
- const uint32_t tmp8 = uint32_add(tmp3, tmp5);
- const uint32_t tmp9 = uint32_add(tmp7, tmp8);
- const uint32_t tmpA = uint32_srl(tmp9, 6);
- const uint32_t tmpB = uint32_add(tmp9, tmpA);
- const uint32_t tmpC = uint32_srl(tmpB, 12);
- const uint32_t tmpD = uint32_srl(tmpB, 24);
- const uint32_t tmpE = uint32_add(tmpB, tmpC);
- const uint32_t tmpF = uint32_add(tmpD, tmpE);
- const uint32_t result = uint32_and(tmpF, 0x3f);
-
- return result;
- }
+ ///
+ uint32_t uint32_li(uint32_t _a);
+
+ ///
+ uint32_t uint32_dec(uint32_t _a);
+
+ ///
+ uint32_t uint32_inc(uint32_t _a);
+
+ ///
+ uint32_t uint32_not(uint32_t _a);
+
+ ///
+ uint32_t uint32_neg(uint32_t _a);
+
+ ///
+ uint32_t uint32_ext(uint32_t _a);
+
+ ///
+ uint32_t uint32_and(uint32_t _a, uint32_t _b);
+
+ ///
+ uint32_t uint32_andc(uint32_t _a, uint32_t _b);
+
+ ///
+ uint32_t uint32_xor(uint32_t _a, uint32_t _b);
+
+ ///
+ uint32_t uint32_xorl(uint32_t _a, uint32_t _b);
+
+ ///
+ uint32_t uint32_or(uint32_t _a, uint32_t _b);
+
+ ///
+ uint32_t uint32_orc(uint32_t _a, uint32_t _b);
+
+ ///
+ uint32_t uint32_sll(uint32_t _a, int _sa);
+
+ ///
+ uint32_t uint32_srl(uint32_t _a, int _sa);
+
+ ///
+ uint32_t uint32_sra(uint32_t _a, int _sa);
+
+ ///
+ uint32_t uint32_rol(uint32_t _a, int _sa);
+
+ ///
+ uint32_t uint32_ror(uint32_t _a, int _sa);
+
+ ///
+ uint32_t uint32_add(uint32_t _a, uint32_t _b);
+
+ ///
+ uint32_t uint32_sub(uint32_t _a, uint32_t _b);
+
+ ///
+ uint32_t uint32_mul(uint32_t _a, uint32_t _b);
+
+ ///
+ uint32_t uint32_div(uint32_t _a, uint32_t _b);
+
+ ///
+ uint32_t uint32_mod(uint32_t _a, uint32_t _b);
+
+ ///
+ uint32_t uint32_cmpeq(uint32_t _a, uint32_t _b);
+
+ ///
+ uint32_t uint32_cmpneq(uint32_t _a, uint32_t _b);
+
+ ///
+ uint32_t uint32_cmplt(uint32_t _a, uint32_t _b);
+
+ ///
+ uint32_t uint32_cmple(uint32_t _a, uint32_t _b);
+
+ ///
+ uint32_t uint32_cmpgt(uint32_t _a, uint32_t _b);
+
+ ///
+ uint32_t uint32_cmpge(uint32_t _a, uint32_t _b);
+
+ ///
+ uint32_t uint32_setnz(uint32_t _a);
+
+ ///
+ uint32_t uint32_satadd(uint32_t _a, uint32_t _b);
+
+ ///
+ uint32_t uint32_satsub(uint32_t _a, uint32_t _b);
+
+ ///
+ uint32_t uint32_satmul(uint32_t _a, uint32_t _b);
+
+ ///
+ uint32_t uint32_sels(uint32_t test, uint32_t _a, uint32_t _b);
+
+ ///
+ uint32_t uint32_selb(uint32_t _mask, uint32_t _a, uint32_t _b);
+
+ ///
+ uint32_t uint32_imin(uint32_t _a, uint32_t _b);
+
+ ///
+ uint32_t uint32_imax(uint32_t _a, uint32_t _b);
+
+ ///
+ uint32_t uint32_min(uint32_t _a, uint32_t _b);
+
+ ///
+ uint32_t uint32_min(uint32_t _a, uint32_t _b, uint32_t _c);
+
+ ///
+ uint32_t uint32_max(uint32_t _a, uint32_t _b);
+
+ ///
+ uint32_t uint32_max(uint32_t _a, uint32_t _b, uint32_t _c);
+
+ ///
+ uint32_t uint32_clamp(uint32_t _a, uint32_t _min, uint32_t _max);
+
+ ///
+ uint32_t uint32_iclamp(uint32_t _a, uint32_t _min, uint32_t _max);
+
+ ///
+ uint32_t uint32_incwrap(uint32_t _val, uint32_t _min, uint32_t _max);
+
+ ///
+ uint32_t uint32_decwrap(uint32_t _val, uint32_t _min, uint32_t _max);
+
+ ///
+ uint32_t uint32_cntbits_ref(uint32_t _val);
/// Count number of bits set.
- inline uint32_t uint32_cntbits(uint32_t _val)
- {
-#if BX_COMPILER_GCC || BX_COMPILER_CLANG
- return __builtin_popcount(_val);
-#elif BX_COMPILER_MSVC && BX_PLATFORM_WINDOWS
- return __popcnt(_val);
-#else
- return uint32_cntbits_ref(_val);
-#endif // BX_COMPILER_
- }
-
- inline uint32_t uint32_cntlz_ref(uint32_t _val)
- {
- const uint32_t tmp0 = uint32_srl(_val, 1);
- const uint32_t tmp1 = uint32_or(tmp0, _val);
- const uint32_t tmp2 = uint32_srl(tmp1, 2);
- const uint32_t tmp3 = uint32_or(tmp2, tmp1);
- const uint32_t tmp4 = uint32_srl(tmp3, 4);
- const uint32_t tmp5 = uint32_or(tmp4, tmp3);
- const uint32_t tmp6 = uint32_srl(tmp5, 8);
- const uint32_t tmp7 = uint32_or(tmp6, tmp5);
- const uint32_t tmp8 = uint32_srl(tmp7, 16);
- const uint32_t tmp9 = uint32_or(tmp8, tmp7);
- const uint32_t tmpA = uint32_not(tmp9);
- const uint32_t result = uint32_cntbits(tmpA);
-
- return result;
- }
+ ///
+ uint32_t uint32_cntbits(uint32_t _val);
+
+ ///
+ uint32_t uint32_cntlz_ref(uint32_t _val);
/// Count number of leading zeros.
- inline uint32_t uint32_cntlz(uint32_t _val)
- {
-#if BX_COMPILER_GCC || BX_COMPILER_CLANG
- return __builtin_clz(_val);
-#elif BX_COMPILER_MSVC && BX_PLATFORM_WINDOWS
- unsigned long index;
- _BitScanReverse(&index, _val);
- return 31 - index;
-#else
- return uint32_cntlz_ref(_val);
-#endif // BX_COMPILER_
- }
-
- inline uint32_t uint32_cnttz_ref(uint32_t _val)
- {
- const uint32_t tmp0 = uint32_not(_val);
- const uint32_t tmp1 = uint32_dec(_val);
- const uint32_t tmp2 = uint32_and(tmp0, tmp1);
- const uint32_t result = uint32_cntbits(tmp2);
-
- return result;
- }
-
- inline uint32_t uint32_cnttz(uint32_t _val)
- {
-#if BX_COMPILER_GCC || BX_COMPILER_CLANG
- return __builtin_ctz(_val);
-#elif BX_COMPILER_MSVC && BX_PLATFORM_WINDOWS
- unsigned long index;
- _BitScanForward(&index, _val);
- return index;
-#else
- return uint32_cnttz_ref(_val);
-#endif // BX_COMPILER_
- }
+ ///
+ uint32_t uint32_cntlz(uint32_t _val);
+
+ ///
+ uint32_t uint32_cnttz_ref(uint32_t _val);
+
+ ///
+ uint32_t uint32_cnttz(uint32_t _val);
// shuffle:
// ---- ---- ---- ---- fedc ba98 7654 3210
// to:
// -f-e -d-c -b-a -9-8 -7-6 -5-4 -3-2 -1-0
- inline uint32_t uint32_part1by1(uint32_t _a)
- {
- const uint32_t val = uint32_and(_a, 0xffff);
+ uint32_t uint32_part1by1(uint32_t _a);
- const uint32_t tmp0 = uint32_sll(val, 8);
- const uint32_t tmp1 = uint32_xor(val, tmp0);
- const uint32_t tmp2 = uint32_and(tmp1, 0x00ff00ff);
+ // shuffle:
+ // ---- ---- ---- ---- ---- --98 7654 3210
+ // to:
+ // ---- 9--8 --7- -6-- 5--4 --3- -2-- 1--0
+ ///
+ uint32_t uint32_part1by2(uint32_t _a);
- const uint32_t tmp3 = uint32_sll(tmp2, 4);
- const uint32_t tmp4 = uint32_xor(tmp2, tmp3);
- const uint32_t tmp5 = uint32_and(tmp4, 0x0f0f0f0f);
+ ///
+ uint32_t uint32_testpow2(uint32_t _a);
- const uint32_t tmp6 = uint32_sll(tmp5, 2);
- const uint32_t tmp7 = uint32_xor(tmp5, tmp6);
- const uint32_t tmp8 = uint32_and(tmp7, 0x33333333);
+ ///
+ uint32_t uint32_nextpow2(uint32_t _a);
- const uint32_t tmp9 = uint32_sll(tmp8, 1);
- const uint32_t tmpA = uint32_xor(tmp8, tmp9);
- const uint32_t result = uint32_and(tmpA, 0x55555555);
+ ///
+ uint16_t halfFromFloat(float _a);
- return result;
- }
+ ///
+ float halfToFloat(uint16_t _a);
- // shuffle:
- // ---- ---- ---- ---- ---- --98 7654 3210
- // to:
- // ---- 9--8 --7- -6-- 5--4 --3- -2-- 1--0
- inline uint32_t uint32_part1by2(uint32_t _a)
- {
- const uint32_t val = uint32_and(_a, 0x3ff);
-
- const uint32_t tmp0 = uint32_sll(val, 16);
- const uint32_t tmp1 = uint32_xor(val, tmp0);
- const uint32_t tmp2 = uint32_and(tmp1, 0xff0000ff);
-
- const uint32_t tmp3 = uint32_sll(tmp2, 8);
- const uint32_t tmp4 = uint32_xor(tmp2, tmp3);
- const uint32_t tmp5 = uint32_and(tmp4, 0x0300f00f);
-
- const uint32_t tmp6 = uint32_sll(tmp5, 4);
- const uint32_t tmp7 = uint32_xor(tmp5, tmp6);
- const uint32_t tmp8 = uint32_and(tmp7, 0x030c30c3);
-
- const uint32_t tmp9 = uint32_sll(tmp8, 2);
- const uint32_t tmpA = uint32_xor(tmp8, tmp9);
- const uint32_t result = uint32_and(tmpA, 0x09249249);
-
- return result;
- }
-
- inline uint32_t uint32_testpow2(uint32_t _a)
- {
- const uint32_t tmp0 = uint32_not(_a);
- const uint32_t tmp1 = uint32_inc(tmp0);
- const uint32_t tmp2 = uint32_and(_a, tmp1);
- const uint32_t tmp3 = uint32_cmpeq(tmp2, _a);
- const uint32_t tmp4 = uint32_cmpneq(_a, 0);
- const uint32_t result = uint32_and(tmp3, tmp4);
-
- return result;
- }
-
- inline uint32_t uint32_nextpow2(uint32_t _a)
- {
- const uint32_t tmp0 = uint32_dec(_a);
- const uint32_t tmp1 = uint32_srl(tmp0, 1);
- const uint32_t tmp2 = uint32_or(tmp0, tmp1);
- const uint32_t tmp3 = uint32_srl(tmp2, 2);
- const uint32_t tmp4 = uint32_or(tmp2, tmp3);
- const uint32_t tmp5 = uint32_srl(tmp4, 4);
- const uint32_t tmp6 = uint32_or(tmp4, tmp5);
- const uint32_t tmp7 = uint32_srl(tmp6, 8);
- const uint32_t tmp8 = uint32_or(tmp6, tmp7);
- const uint32_t tmp9 = uint32_srl(tmp8, 16);
- const uint32_t tmpA = uint32_or(tmp8, tmp9);
- const uint32_t result = uint32_inc(tmpA);
-
- return result;
- }
-
- inline uint16_t halfFromFloat(float _a)
- {
- union { uint32_t ui; float flt; } ftou;
- ftou.flt = _a;
-
- const uint32_t one = uint32_li(0x00000001);
- const uint32_t f_s_mask = uint32_li(0x80000000);
- const uint32_t f_e_mask = uint32_li(0x7f800000);
- const uint32_t f_m_mask = uint32_li(0x007fffff);
- const uint32_t f_m_hidden_bit = uint32_li(0x00800000);
- const uint32_t f_m_round_bit = uint32_li(0x00001000);
- const uint32_t f_snan_mask = uint32_li(0x7fc00000);
- const uint32_t f_e_pos = uint32_li(0x00000017);
- const uint32_t h_e_pos = uint32_li(0x0000000a);
- const uint32_t h_e_mask = uint32_li(0x00007c00);
- const uint32_t h_snan_mask = uint32_li(0x00007e00);
- const uint32_t h_e_mask_value = uint32_li(0x0000001f);
- const uint32_t f_h_s_pos_offset = uint32_li(0x00000010);
- const uint32_t f_h_bias_offset = uint32_li(0x00000070);
- const uint32_t f_h_m_pos_offset = uint32_li(0x0000000d);
- const uint32_t h_nan_min = uint32_li(0x00007c01);
- const uint32_t f_h_e_biased_flag = uint32_li(0x0000008f);
- const uint32_t f_s = uint32_and(ftou.ui, f_s_mask);
- const uint32_t f_e = uint32_and(ftou.ui, f_e_mask);
- const uint16_t h_s = (uint16_t)uint32_srl(f_s, f_h_s_pos_offset);
- const uint32_t f_m = uint32_and(ftou.ui, f_m_mask);
- const uint16_t f_e_amount = (uint16_t)uint32_srl(f_e, f_e_pos);
- const uint32_t f_e_half_bias = uint32_sub(f_e_amount, f_h_bias_offset);
- const uint32_t f_snan = uint32_and(ftou.ui, f_snan_mask);
- const uint32_t f_m_round_mask = uint32_and(f_m, f_m_round_bit);
- const uint32_t f_m_round_offset = uint32_sll(f_m_round_mask, one);
- const uint32_t f_m_rounded = uint32_add(f_m, f_m_round_offset);
- const uint32_t f_m_denorm_sa = uint32_sub(one, f_e_half_bias);
- const uint32_t f_m_with_hidden = uint32_or(f_m_rounded, f_m_hidden_bit);
- const uint32_t f_m_denorm = uint32_srl(f_m_with_hidden, f_m_denorm_sa);
- const uint32_t h_m_denorm = uint32_srl(f_m_denorm, f_h_m_pos_offset);
- const uint32_t f_m_rounded_overflow = uint32_and(f_m_rounded, f_m_hidden_bit);
- const uint32_t m_nan = uint32_srl(f_m, f_h_m_pos_offset);
- const uint32_t h_em_nan = uint32_or(h_e_mask, m_nan);
- const uint32_t h_e_norm_overflow_offset = uint32_inc(f_e_half_bias);
- const uint32_t h_e_norm_overflow = uint32_sll(h_e_norm_overflow_offset, h_e_pos);
- const uint32_t h_e_norm = uint32_sll(f_e_half_bias, h_e_pos);
- const uint32_t h_m_norm = uint32_srl(f_m_rounded, f_h_m_pos_offset);
- const uint32_t h_em_norm = uint32_or(h_e_norm, h_m_norm);
- const uint32_t is_h_ndenorm_msb = uint32_sub(f_h_bias_offset, f_e_amount);
- const uint32_t is_f_e_flagged_msb = uint32_sub(f_h_e_biased_flag, f_e_half_bias);
- const uint32_t is_h_denorm_msb = uint32_not(is_h_ndenorm_msb);
- const uint32_t is_f_m_eqz_msb = uint32_dec(f_m);
- const uint32_t is_h_nan_eqz_msb = uint32_dec(m_nan);
- const uint32_t is_f_inf_msb = uint32_and(is_f_e_flagged_msb, is_f_m_eqz_msb);
- const uint32_t is_f_nan_underflow_msb = uint32_and(is_f_e_flagged_msb, is_h_nan_eqz_msb);
- const uint32_t is_e_overflow_msb = uint32_sub(h_e_mask_value, f_e_half_bias);
- const uint32_t is_h_inf_msb = uint32_or(is_e_overflow_msb, is_f_inf_msb);
- const uint32_t is_f_nsnan_msb = uint32_sub(f_snan, f_snan_mask);
- const uint32_t is_m_norm_overflow_msb = uint32_neg(f_m_rounded_overflow);
- const uint32_t is_f_snan_msb = uint32_not(is_f_nsnan_msb);
- const uint32_t h_em_overflow_result = uint32_sels(is_m_norm_overflow_msb, h_e_norm_overflow, h_em_norm);
- const uint32_t h_em_nan_result = uint32_sels(is_f_e_flagged_msb, h_em_nan, h_em_overflow_result);
- const uint32_t h_em_nan_underflow_result = uint32_sels(is_f_nan_underflow_msb, h_nan_min, h_em_nan_result);
- const uint32_t h_em_inf_result = uint32_sels(is_h_inf_msb, h_e_mask, h_em_nan_underflow_result);
- const uint32_t h_em_denorm_result = uint32_sels(is_h_denorm_msb, h_m_denorm, h_em_inf_result);
- const uint32_t h_em_snan_result = uint32_sels(is_f_snan_msb, h_snan_mask, h_em_denorm_result);
- const uint32_t h_result = uint32_or(h_s, h_em_snan_result);
-
- return (uint16_t)(h_result);
- }
-
- inline float halfToFloat(uint16_t _a)
- {
- const uint32_t h_e_mask = uint32_li(0x00007c00);
- const uint32_t h_m_mask = uint32_li(0x000003ff);
- const uint32_t h_s_mask = uint32_li(0x00008000);
- const uint32_t h_f_s_pos_offset = uint32_li(0x00000010);
- const uint32_t h_f_e_pos_offset = uint32_li(0x0000000d);
- const uint32_t h_f_bias_offset = uint32_li(0x0001c000);
- const uint32_t f_e_mask = uint32_li(0x7f800000);
- const uint32_t f_m_mask = uint32_li(0x007fffff);
- const uint32_t h_f_e_denorm_bias = uint32_li(0x0000007e);
- const uint32_t h_f_m_denorm_sa_bias = uint32_li(0x00000008);
- const uint32_t f_e_pos = uint32_li(0x00000017);
- const uint32_t h_e_mask_minus_one = uint32_li(0x00007bff);
- const uint32_t h_e = uint32_and(_a, h_e_mask);
- const uint32_t h_m = uint32_and(_a, h_m_mask);
- const uint32_t h_s = uint32_and(_a, h_s_mask);
- const uint32_t h_e_f_bias = uint32_add(h_e, h_f_bias_offset);
- const uint32_t h_m_nlz = uint32_cntlz(h_m);
- const uint32_t f_s = uint32_sll(h_s, h_f_s_pos_offset);
- const uint32_t f_e = uint32_sll(h_e_f_bias, h_f_e_pos_offset);
- const uint32_t f_m = uint32_sll(h_m, h_f_e_pos_offset);
- const uint32_t f_em = uint32_or(f_e, f_m);
- const uint32_t h_f_m_sa = uint32_sub(h_m_nlz, h_f_m_denorm_sa_bias);
- const uint32_t f_e_denorm_unpacked = uint32_sub(h_f_e_denorm_bias, h_f_m_sa);
- const uint32_t h_f_m = uint32_sll(h_m, h_f_m_sa);
- const uint32_t f_m_denorm = uint32_and(h_f_m, f_m_mask);
- const uint32_t f_e_denorm = uint32_sll(f_e_denorm_unpacked, f_e_pos);
- const uint32_t f_em_denorm = uint32_or(f_e_denorm, f_m_denorm);
- const uint32_t f_em_nan = uint32_or(f_e_mask, f_m);
- const uint32_t is_e_eqz_msb = uint32_dec(h_e);
- const uint32_t is_m_nez_msb = uint32_neg(h_m);
- const uint32_t is_e_flagged_msb = uint32_sub(h_e_mask_minus_one, h_e);
- const uint32_t is_zero_msb = uint32_andc(is_e_eqz_msb, is_m_nez_msb);
- const uint32_t is_inf_msb = uint32_andc(is_e_flagged_msb, is_m_nez_msb);
- const uint32_t is_denorm_msb = uint32_and(is_m_nez_msb, is_e_eqz_msb);
- const uint32_t is_nan_msb = uint32_and(is_e_flagged_msb, is_m_nez_msb);
- const uint32_t is_zero = uint32_ext(is_zero_msb);
- const uint32_t f_zero_result = uint32_andc(f_em, is_zero);
- const uint32_t f_denorm_result = uint32_sels(is_denorm_msb, f_em_denorm, f_zero_result);
- const uint32_t f_inf_result = uint32_sels(is_inf_msb, f_e_mask, f_denorm_result);
- const uint32_t f_nan_result = uint32_sels(is_nan_msb, f_em_nan, f_inf_result);
- const uint32_t f_result = uint32_or(f_s, f_nan_result);
-
- union { uint32_t ui; float flt; } utof;
- utof.ui = f_result;
- return utof.flt;
- }
-
- inline uint16_t uint16_min(uint16_t _a, uint16_t _b)
- {
- return _a > _b ? _b : _a;
- }
-
- inline uint16_t uint16_max(uint16_t _a, uint16_t _b)
- {
- return _a < _b ? _b : _a;
- }
-
- inline int64_t int64_min(int64_t _a, int64_t _b)
- {
- return _a < _b ? _a : _b;
- }
-
- inline int64_t int64_max(int64_t _a, int64_t _b)
- {
- return _a > _b ? _a : _b;
- }
-
- inline int64_t int64_clamp(int64_t _a, int64_t _min, int64_t _max)
- {
- const int64_t min = int64_min(_a, _max);
- const int64_t result = int64_max(_min, min);
-
- return result;
- }
-
- inline uint64_t uint64_cntbits_ref(uint64_t _val)
- {
- const uint32_t lo = uint32_t(_val&UINT32_MAX);
- const uint32_t hi = uint32_t(_val>>32);
-
- const uint32_t total = bx::uint32_cntbits(lo)
- + bx::uint32_cntbits(hi);
-
- return total;
- }
+ ///
+ uint16_t uint16_min(uint16_t _a, uint16_t _b);
+
+ ///
+ uint16_t uint16_max(uint16_t _a, uint16_t _b);
+
+ ///
+ int64_t int64_min(int64_t _a, int64_t _b);
+
+ ///
+ int64_t int64_max(int64_t _a, int64_t _b);
+
+ ///
+ int64_t int64_clamp(int64_t _a, int64_t _min, int64_t _max);
+
+ ///
+ uint32_t uint64_cntbits_ref(uint64_t _val);
/// Count number of bits set.
- inline uint64_t uint64_cntbits(uint64_t _val)
- {
-#if BX_COMPILER_GCC || BX_COMPILER_CLANG
- return __builtin_popcountll(_val);
-#elif BX_COMPILER_MSVC && BX_ARCH_64BIT
- return __popcnt64(_val);
-#else
- return uint64_cntbits_ref(_val);
-#endif // BX_COMPILER_
- }
-
- inline uint64_t uint64_cntlz_ref(uint64_t _val)
- {
- return _val & UINT64_C(0xffffffff00000000)
- ? uint32_cntlz(uint32_t(_val>>32) )
- : uint32_cntlz(uint32_t(_val) ) + 32
- ;
- }
+ ///
+ uint32_t uint64_cntbits(uint64_t _val);
+
+ ///
+ uint32_t uint64_cntlz_ref(uint64_t _val);
/// Count number of leading zeros.
- inline uint64_t uint64_cntlz(uint64_t _val)
- {
-#if BX_COMPILER_GCC || BX_COMPILER_CLANG
- return __builtin_clzll(_val);
-#elif BX_COMPILER_MSVC && BX_PLATFORM_WINDOWS && BX_ARCH_64BIT
- unsigned long index;
- _BitScanReverse64(&index, _val);
- return 63 - index;
-#else
- return uint64_cntlz_ref(_val);
-#endif // BX_COMPILER_
- }
-
- inline uint64_t uint64_cnttz_ref(uint64_t _val)
- {
- return _val & UINT64_C(0xffffffff)
- ? uint32_cnttz(uint32_t(_val) )
- : uint32_cnttz(uint32_t(_val>>32) ) + 32
- ;
- }
-
- inline uint64_t uint64_cnttz(uint64_t _val)
- {
-#if BX_COMPILER_GCC || BX_COMPILER_CLANG
- return __builtin_ctzll(_val);
-#elif BX_COMPILER_MSVC && BX_PLATFORM_WINDOWS && BX_ARCH_64BIT
- unsigned long index;
- _BitScanForward64(&index, _val);
- return index;
-#else
- return uint64_cnttz_ref(_val);
-#endif // BX_COMPILER_
- }
-
- inline uint64_t uint64_sll(uint64_t _a, int _sa)
- {
- return _a << _sa;
- }
-
- inline uint64_t uint64_srl(uint64_t _a, int _sa)
- {
- return _a >> _sa;
- }
-
- inline uint64_t uint64_sra(uint64_t _a, int _sa)
- {
- return ( (int64_t)_a) >> _sa;
- }
-
- inline uint64_t uint64_rol(uint64_t _a, int _sa)
- {
- return ( _a << _sa) | (_a >> (32-_sa) );
- }
-
- inline uint64_t uint64_ror(uint64_t _a, int _sa)
- {
- return ( _a >> _sa) | (_a << (32-_sa) );
- }
-
- inline uint64_t uint64_add(uint64_t _a, uint64_t _b)
- {
- return _a + _b;
- }
-
- inline uint64_t uint64_sub(uint64_t _a, uint64_t _b)
- {
- return _a - _b;
- }
-
- inline uint64_t uint64_mul(uint64_t _a, uint64_t _b)
- {
- return _a * _b;
- }
+ ///
+ uint32_t uint64_cntlz(uint64_t _val);
+
+ ///
+ uint32_t uint64_cnttz_ref(uint64_t _val);
+
+ ///
+ uint32_t uint64_cnttz(uint64_t _val);
+
+ ///
+ uint64_t uint64_sll(uint64_t _a, int _sa);
+
+ ///
+ uint64_t uint64_srl(uint64_t _a, int _sa);
+
+ ///
+ uint64_t uint64_sra(uint64_t _a, int _sa);
+
+ ///
+ uint64_t uint64_rol(uint64_t _a, int _sa);
+
+ ///
+ uint64_t uint64_ror(uint64_t _a, int _sa);
+
+ ///
+ uint64_t uint64_add(uint64_t _a, uint64_t _b);
+
+ ///
+ uint64_t uint64_sub(uint64_t _a, uint64_t _b);
+
+ ///
+ uint64_t uint64_mul(uint64_t _a, uint64_t _b);
/// Greatest common divisor.
- inline uint32_t uint32_gcd(uint32_t _a, uint32_t _b)
- {
- do
- {
- uint32_t tmp = _a % _b;
- _a = _b;
- _b = tmp;
- }
- while (_b);
-
- return _a;
- }
+ ///
+ uint32_t uint32_gcd(uint32_t _a, uint32_t _b);
/// Least common multiple.
- inline uint32_t uint32_lcm(uint32_t _a, uint32_t _b)
- {
- return _a * (_b / uint32_gcd(_a, _b) );
- }
+ ///
+ uint32_t uint32_lcm(uint32_t _a, uint32_t _b);
/// Align to arbitrary stride.
- inline uint32_t strideAlign(uint32_t _offset, uint32_t _stride)
- {
- const uint32_t mod = uint32_mod(_offset, _stride);
- const uint32_t add = uint32_sub(_stride, mod);
- const uint32_t mask = uint32_cmpeq(mod, 0);
- const uint32_t tmp = uint32_selb(mask, 0, add);
- const uint32_t result = uint32_add(_offset, tmp);
-
- return result;
- }
+ ///
+ uint32_t strideAlign(uint32_t _offset, uint32_t _stride);
/// Align to arbitrary stride and 16-bytes.
- inline uint32_t strideAlign16(uint32_t _offset, uint32_t _stride)
- {
- const uint32_t align = uint32_lcm(16, _stride);
- const uint32_t mod = uint32_mod(_offset, align);
- const uint32_t mask = uint32_cmpeq(mod, 0);
- const uint32_t tmp0 = uint32_selb(mask, 0, align);
- const uint32_t tmp1 = uint32_add(_offset, tmp0);
- const uint32_t result = uint32_sub(tmp1, mod);
-
- return result;
- }
+ ///
+ uint32_t strideAlign16(uint32_t _offset, uint32_t _stride);
/// Align to arbitrary stride and 256-bytes.
- inline uint32_t strideAlign256(uint32_t _offset, uint32_t _stride)
- {
- const uint32_t align = uint32_lcm(256, _stride);
- const uint32_t mod = uint32_mod(_offset, align);
- const uint32_t mask = uint32_cmpeq(mod, 0);
- const uint32_t tmp0 = uint32_selb(mask, 0, align);
- const uint32_t tmp1 = uint32_add(_offset, tmp0);
- const uint32_t result = uint32_sub(tmp1, mod);
-
- return result;
- }
+ ///
+ uint32_t strideAlign256(uint32_t _offset, uint32_t _stride);
} // namespace bx
+#include "uint32_t.inl"
+
#endif // BX_UINT32_T_H_HEADER_GUARD
diff --git a/3rdparty/bx/include/bx/uint32_t.inl b/3rdparty/bx/include/bx/uint32_t.inl
new file mode 100644
index 00000000000..8a66a07ca2d
--- /dev/null
+++ b/3rdparty/bx/include/bx/uint32_t.inl
@@ -0,0 +1,781 @@
+/*
+ * Copyright 2010-2017 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ */
+
+// Copyright 2006 Mike Acton <macton@gmail.com>
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE
+
+#ifndef BX_UINT32_T_H_HEADER_GUARD
+# error "Must be included from bx/uint32_t.h"
+#endif // BX_UINT32_T_H_HEADER_GUARD
+
+namespace bx
+{
+ inline uint32_t uint32_li(uint32_t _a)
+ {
+ return _a;
+ }
+
+ inline uint32_t uint32_dec(uint32_t _a)
+ {
+ return _a - 1;
+ }
+
+ inline uint32_t uint32_inc(uint32_t _a)
+ {
+ return _a + 1;
+ }
+
+ inline uint32_t uint32_not(uint32_t _a)
+ {
+ return ~_a;
+ }
+
+ inline uint32_t uint32_neg(uint32_t _a)
+ {
+ return -(int32_t)_a;
+ }
+
+ inline uint32_t uint32_ext(uint32_t _a)
+ {
+ return ( (int32_t)_a)>>31;
+ }
+
+ inline uint32_t uint32_and(uint32_t _a, uint32_t _b)
+ {
+ return _a & _b;
+ }
+
+ inline uint32_t uint32_andc(uint32_t _a, uint32_t _b)
+ {
+ return _a & ~_b;
+ }
+
+ inline uint32_t uint32_xor(uint32_t _a, uint32_t _b)
+ {
+ return _a ^ _b;
+ }
+
+ inline uint32_t uint32_xorl(uint32_t _a, uint32_t _b)
+ {
+ return !_a != !_b;
+ }
+
+ inline uint32_t uint32_or(uint32_t _a, uint32_t _b)
+ {
+ return _a | _b;
+ }
+
+ inline uint32_t uint32_orc(uint32_t _a, uint32_t _b)
+ {
+ return _a | ~_b;
+ }
+
+ inline uint32_t uint32_sll(uint32_t _a, int _sa)
+ {
+ return _a << _sa;
+ }
+
+ inline uint32_t uint32_srl(uint32_t _a, int _sa)
+ {
+ return _a >> _sa;
+ }
+
+ inline uint32_t uint32_sra(uint32_t _a, int _sa)
+ {
+ return ( (int32_t)_a) >> _sa;
+ }
+
+ inline uint32_t uint32_rol(uint32_t _a, int _sa)
+ {
+ return ( _a << _sa) | (_a >> (32-_sa) );
+ }
+
+ inline uint32_t uint32_ror(uint32_t _a, int _sa)
+ {
+ return ( _a >> _sa) | (_a << (32-_sa) );
+ }
+
+ inline uint32_t uint32_add(uint32_t _a, uint32_t _b)
+ {
+ return _a + _b;
+ }
+
+ inline uint32_t uint32_sub(uint32_t _a, uint32_t _b)
+ {
+ return _a - _b;
+ }
+
+ inline uint32_t uint32_mul(uint32_t _a, uint32_t _b)
+ {
+ return _a * _b;
+ }
+
+ inline uint32_t uint32_div(uint32_t _a, uint32_t _b)
+ {
+ return (_a / _b);
+ }
+
+ inline uint32_t uint32_mod(uint32_t _a, uint32_t _b)
+ {
+ return (_a % _b);
+ }
+
+ inline uint32_t uint32_cmpeq(uint32_t _a, uint32_t _b)
+ {
+ return -(_a == _b);
+ }
+
+ inline uint32_t uint32_cmpneq(uint32_t _a, uint32_t _b)
+ {
+ return -(_a != _b);
+ }
+
+ inline uint32_t uint32_cmplt(uint32_t _a, uint32_t _b)
+ {
+ return -(_a < _b);
+ }
+
+ inline uint32_t uint32_cmple(uint32_t _a, uint32_t _b)
+ {
+ return -(_a <= _b);
+ }
+
+ inline uint32_t uint32_cmpgt(uint32_t _a, uint32_t _b)
+ {
+ return -(_a > _b);
+ }
+
+ inline uint32_t uint32_cmpge(uint32_t _a, uint32_t _b)
+ {
+ return -(_a >= _b);
+ }
+
+ inline uint32_t uint32_setnz(uint32_t _a)
+ {
+ return -!!_a;
+ }
+
+ inline uint32_t uint32_satadd(uint32_t _a, uint32_t _b)
+ {
+ const uint32_t add = uint32_add(_a, _b);
+ const uint32_t lt = uint32_cmplt(add, _a);
+ const uint32_t result = uint32_or(add, lt);
+
+ return result;
+ }
+
+ inline uint32_t uint32_satsub(uint32_t _a, uint32_t _b)
+ {
+ const uint32_t sub = uint32_sub(_a, _b);
+ const uint32_t le = uint32_cmple(sub, _a);
+ const uint32_t result = uint32_and(sub, le);
+
+ return result;
+ }
+
+ inline uint32_t uint32_satmul(uint32_t _a, uint32_t _b)
+ {
+ const uint64_t mul = (uint64_t)_a * (uint64_t)_b;
+ const uint32_t hi = mul >> 32;
+ const uint32_t nz = uint32_setnz(hi);
+ const uint32_t result = uint32_or(uint32_t(mul), nz);
+
+ return result;
+ }
+
+ inline uint32_t uint32_sels(uint32_t test, uint32_t _a, uint32_t _b)
+ {
+ const uint32_t mask = uint32_ext(test);
+ const uint32_t sel_a = uint32_and(_a, mask);
+ const uint32_t sel_b = uint32_andc(_b, mask);
+ const uint32_t result = uint32_or(sel_a, sel_b);
+
+ return (result);
+ }
+
+ inline uint32_t uint32_selb(uint32_t _mask, uint32_t _a, uint32_t _b)
+ {
+ const uint32_t sel_a = uint32_and(_a, _mask);
+ const uint32_t sel_b = uint32_andc(_b, _mask);
+ const uint32_t result = uint32_or(sel_a, sel_b);
+
+ return (result);
+ }
+
+ inline uint32_t uint32_imin(uint32_t _a, uint32_t _b)
+ {
+ const uint32_t a_sub_b = uint32_sub(_a, _b);
+ const uint32_t result = uint32_sels(a_sub_b, _a, _b);
+
+ return result;
+ }
+
+ inline uint32_t uint32_imax(uint32_t _a, uint32_t _b)
+ {
+ const uint32_t b_sub_a = uint32_sub(_b, _a);
+ const uint32_t result = uint32_sels(b_sub_a, _a, _b);
+
+ return result;
+ }
+
+ inline uint32_t uint32_min(uint32_t _a, uint32_t _b)
+ {
+ return _a > _b ? _b : _a;
+ }
+
+ inline uint32_t uint32_min(uint32_t _a, uint32_t _b, uint32_t _c)
+ {
+ return uint32_min(_a, uint32_min(_b, _c) );
+ }
+
+ inline uint32_t uint32_max(uint32_t _a, uint32_t _b)
+ {
+ return _a > _b ? _a : _b;
+ }
+
+ inline uint32_t uint32_max(uint32_t _a, uint32_t _b, uint32_t _c)
+ {
+ return uint32_max(_a, uint32_max(_b, _c) );
+ }
+
+ inline uint32_t uint32_clamp(uint32_t _a, uint32_t _min, uint32_t _max)
+ {
+ const uint32_t tmp = uint32_max(_a, _min);
+ const uint32_t result = uint32_min(tmp, _max);
+
+ return result;
+ }
+
+ inline uint32_t uint32_iclamp(uint32_t _a, uint32_t _min, uint32_t _max)
+ {
+ const uint32_t tmp = uint32_imax(_a, _min);
+ const uint32_t result = uint32_imin(tmp, _max);
+
+ return result;
+ }
+
+ inline uint32_t uint32_incwrap(uint32_t _val, uint32_t _min, uint32_t _max)
+ {
+ const uint32_t inc = uint32_inc(_val);
+ const uint32_t max_diff = uint32_sub(_max, _val);
+ const uint32_t neg_max_diff = uint32_neg(max_diff);
+ const uint32_t max_or = uint32_or(max_diff, neg_max_diff);
+ const uint32_t max_diff_nz = uint32_ext(max_or);
+ const uint32_t result = uint32_selb(max_diff_nz, inc, _min);
+
+ return result;
+ }
+
+ inline uint32_t uint32_decwrap(uint32_t _val, uint32_t _min, uint32_t _max)
+ {
+ const uint32_t dec = uint32_dec(_val);
+ const uint32_t min_diff = uint32_sub(_min, _val);
+ const uint32_t neg_min_diff = uint32_neg(min_diff);
+ const uint32_t min_or = uint32_or(min_diff, neg_min_diff);
+ const uint32_t min_diff_nz = uint32_ext(min_or);
+ const uint32_t result = uint32_selb(min_diff_nz, dec, _max);
+
+ return result;
+ }
+
+ inline uint32_t uint32_cntbits_ref(uint32_t _val)
+ {
+ const uint32_t tmp0 = uint32_srl(_val, 1);
+ const uint32_t tmp1 = uint32_and(tmp0, 0x55555555);
+ const uint32_t tmp2 = uint32_sub(_val, tmp1);
+ const uint32_t tmp3 = uint32_and(tmp2, 0xc30c30c3);
+ const uint32_t tmp4 = uint32_srl(tmp2, 2);
+ const uint32_t tmp5 = uint32_and(tmp4, 0xc30c30c3);
+ const uint32_t tmp6 = uint32_srl(tmp2, 4);
+ const uint32_t tmp7 = uint32_and(tmp6, 0xc30c30c3);
+ const uint32_t tmp8 = uint32_add(tmp3, tmp5);
+ const uint32_t tmp9 = uint32_add(tmp7, tmp8);
+ const uint32_t tmpA = uint32_srl(tmp9, 6);
+ const uint32_t tmpB = uint32_add(tmp9, tmpA);
+ const uint32_t tmpC = uint32_srl(tmpB, 12);
+ const uint32_t tmpD = uint32_srl(tmpB, 24);
+ const uint32_t tmpE = uint32_add(tmpB, tmpC);
+ const uint32_t tmpF = uint32_add(tmpD, tmpE);
+ const uint32_t result = uint32_and(tmpF, 0x3f);
+
+ return result;
+ }
+
+ /// Count number of bits set.
+ inline uint32_t uint32_cntbits(uint32_t _val)
+ {
+#if BX_COMPILER_GCC || BX_COMPILER_CLANG
+ return __builtin_popcount(_val);
+#elif BX_COMPILER_MSVC && BX_PLATFORM_WINDOWS
+ return __popcnt(_val);
+#else
+ return uint32_cntbits_ref(_val);
+#endif // BX_COMPILER_
+ }
+
+ inline uint32_t uint32_cntlz_ref(uint32_t _val)
+ {
+ const uint32_t tmp0 = uint32_srl(_val, 1);
+ const uint32_t tmp1 = uint32_or(tmp0, _val);
+ const uint32_t tmp2 = uint32_srl(tmp1, 2);
+ const uint32_t tmp3 = uint32_or(tmp2, tmp1);
+ const uint32_t tmp4 = uint32_srl(tmp3, 4);
+ const uint32_t tmp5 = uint32_or(tmp4, tmp3);
+ const uint32_t tmp6 = uint32_srl(tmp5, 8);
+ const uint32_t tmp7 = uint32_or(tmp6, tmp5);
+ const uint32_t tmp8 = uint32_srl(tmp7, 16);
+ const uint32_t tmp9 = uint32_or(tmp8, tmp7);
+ const uint32_t tmpA = uint32_not(tmp9);
+ const uint32_t result = uint32_cntbits(tmpA);
+
+ return result;
+ }
+
+ /// Count number of leading zeros.
+ inline uint32_t uint32_cntlz(uint32_t _val)
+ {
+#if BX_COMPILER_GCC || BX_COMPILER_CLANG
+ return __builtin_clz(_val);
+#elif BX_COMPILER_MSVC && BX_PLATFORM_WINDOWS
+ unsigned long index;
+ _BitScanReverse(&index, _val);
+ return 31 - index;
+#else
+ return uint32_cntlz_ref(_val);
+#endif // BX_COMPILER_
+ }
+
+ inline uint32_t uint32_cnttz_ref(uint32_t _val)
+ {
+ const uint32_t tmp0 = uint32_not(_val);
+ const uint32_t tmp1 = uint32_dec(_val);
+ const uint32_t tmp2 = uint32_and(tmp0, tmp1);
+ const uint32_t result = uint32_cntbits(tmp2);
+
+ return result;
+ }
+
+ inline uint32_t uint32_cnttz(uint32_t _val)
+ {
+#if BX_COMPILER_GCC || BX_COMPILER_CLANG
+ return __builtin_ctz(_val);
+#elif BX_COMPILER_MSVC && BX_PLATFORM_WINDOWS
+ unsigned long index;
+ _BitScanForward(&index, _val);
+ return index;
+#else
+ return uint32_cnttz_ref(_val);
+#endif // BX_COMPILER_
+ }
+
+ // shuffle:
+ // ---- ---- ---- ---- fedc ba98 7654 3210
+ // to:
+ // -f-e -d-c -b-a -9-8 -7-6 -5-4 -3-2 -1-0
+ inline uint32_t uint32_part1by1(uint32_t _a)
+ {
+ const uint32_t val = uint32_and(_a, 0xffff);
+
+ const uint32_t tmp0 = uint32_sll(val, 8);
+ const uint32_t tmp1 = uint32_xor(val, tmp0);
+ const uint32_t tmp2 = uint32_and(tmp1, 0x00ff00ff);
+
+ const uint32_t tmp3 = uint32_sll(tmp2, 4);
+ const uint32_t tmp4 = uint32_xor(tmp2, tmp3);
+ const uint32_t tmp5 = uint32_and(tmp4, 0x0f0f0f0f);
+
+ const uint32_t tmp6 = uint32_sll(tmp5, 2);
+ const uint32_t tmp7 = uint32_xor(tmp5, tmp6);
+ const uint32_t tmp8 = uint32_and(tmp7, 0x33333333);
+
+ const uint32_t tmp9 = uint32_sll(tmp8, 1);
+ const uint32_t tmpA = uint32_xor(tmp8, tmp9);
+ const uint32_t result = uint32_and(tmpA, 0x55555555);
+
+ return result;
+ }
+
+ // shuffle:
+ // ---- ---- ---- ---- ---- --98 7654 3210
+ // to:
+ // ---- 9--8 --7- -6-- 5--4 --3- -2-- 1--0
+ inline uint32_t uint32_part1by2(uint32_t _a)
+ {
+ const uint32_t val = uint32_and(_a, 0x3ff);
+
+ const uint32_t tmp0 = uint32_sll(val, 16);
+ const uint32_t tmp1 = uint32_xor(val, tmp0);
+ const uint32_t tmp2 = uint32_and(tmp1, 0xff0000ff);
+
+ const uint32_t tmp3 = uint32_sll(tmp2, 8);
+ const uint32_t tmp4 = uint32_xor(tmp2, tmp3);
+ const uint32_t tmp5 = uint32_and(tmp4, 0x0300f00f);
+
+ const uint32_t tmp6 = uint32_sll(tmp5, 4);
+ const uint32_t tmp7 = uint32_xor(tmp5, tmp6);
+ const uint32_t tmp8 = uint32_and(tmp7, 0x030c30c3);
+
+ const uint32_t tmp9 = uint32_sll(tmp8, 2);
+ const uint32_t tmpA = uint32_xor(tmp8, tmp9);
+ const uint32_t result = uint32_and(tmpA, 0x09249249);
+
+ return result;
+ }
+
+ inline uint32_t uint32_testpow2(uint32_t _a)
+ {
+ const uint32_t tmp0 = uint32_not(_a);
+ const uint32_t tmp1 = uint32_inc(tmp0);
+ const uint32_t tmp2 = uint32_and(_a, tmp1);
+ const uint32_t tmp3 = uint32_cmpeq(tmp2, _a);
+ const uint32_t tmp4 = uint32_cmpneq(_a, 0);
+ const uint32_t result = uint32_and(tmp3, tmp4);
+
+ return result;
+ }
+
+ inline uint32_t uint32_nextpow2(uint32_t _a)
+ {
+ const uint32_t tmp0 = uint32_dec(_a);
+ const uint32_t tmp1 = uint32_srl(tmp0, 1);
+ const uint32_t tmp2 = uint32_or(tmp0, tmp1);
+ const uint32_t tmp3 = uint32_srl(tmp2, 2);
+ const uint32_t tmp4 = uint32_or(tmp2, tmp3);
+ const uint32_t tmp5 = uint32_srl(tmp4, 4);
+ const uint32_t tmp6 = uint32_or(tmp4, tmp5);
+ const uint32_t tmp7 = uint32_srl(tmp6, 8);
+ const uint32_t tmp8 = uint32_or(tmp6, tmp7);
+ const uint32_t tmp9 = uint32_srl(tmp8, 16);
+ const uint32_t tmpA = uint32_or(tmp8, tmp9);
+ const uint32_t result = uint32_inc(tmpA);
+
+ return result;
+ }
+
+ inline uint16_t halfFromFloat(float _a)
+ {
+ union { uint32_t ui; float flt; } ftou;
+ ftou.flt = _a;
+
+ const uint32_t one = uint32_li(0x00000001);
+ const uint32_t f_s_mask = uint32_li(0x80000000);
+ const uint32_t f_e_mask = uint32_li(0x7f800000);
+ const uint32_t f_m_mask = uint32_li(0x007fffff);
+ const uint32_t f_m_hidden_bit = uint32_li(0x00800000);
+ const uint32_t f_m_round_bit = uint32_li(0x00001000);
+ const uint32_t f_snan_mask = uint32_li(0x7fc00000);
+ const uint32_t f_e_pos = uint32_li(0x00000017);
+ const uint32_t h_e_pos = uint32_li(0x0000000a);
+ const uint32_t h_e_mask = uint32_li(0x00007c00);
+ const uint32_t h_snan_mask = uint32_li(0x00007e00);
+ const uint32_t h_e_mask_value = uint32_li(0x0000001f);
+ const uint32_t f_h_s_pos_offset = uint32_li(0x00000010);
+ const uint32_t f_h_bias_offset = uint32_li(0x00000070);
+ const uint32_t f_h_m_pos_offset = uint32_li(0x0000000d);
+ const uint32_t h_nan_min = uint32_li(0x00007c01);
+ const uint32_t f_h_e_biased_flag = uint32_li(0x0000008f);
+ const uint32_t f_s = uint32_and(ftou.ui, f_s_mask);
+ const uint32_t f_e = uint32_and(ftou.ui, f_e_mask);
+ const uint16_t h_s = (uint16_t)uint32_srl(f_s, f_h_s_pos_offset);
+ const uint32_t f_m = uint32_and(ftou.ui, f_m_mask);
+ const uint16_t f_e_amount = (uint16_t)uint32_srl(f_e, f_e_pos);
+ const uint32_t f_e_half_bias = uint32_sub(f_e_amount, f_h_bias_offset);
+ const uint32_t f_snan = uint32_and(ftou.ui, f_snan_mask);
+ const uint32_t f_m_round_mask = uint32_and(f_m, f_m_round_bit);
+ const uint32_t f_m_round_offset = uint32_sll(f_m_round_mask, one);
+ const uint32_t f_m_rounded = uint32_add(f_m, f_m_round_offset);
+ const uint32_t f_m_denorm_sa = uint32_sub(one, f_e_half_bias);
+ const uint32_t f_m_with_hidden = uint32_or(f_m_rounded, f_m_hidden_bit);
+ const uint32_t f_m_denorm = uint32_srl(f_m_with_hidden, f_m_denorm_sa);
+ const uint32_t h_m_denorm = uint32_srl(f_m_denorm, f_h_m_pos_offset);
+ const uint32_t f_m_rounded_overflow = uint32_and(f_m_rounded, f_m_hidden_bit);
+ const uint32_t m_nan = uint32_srl(f_m, f_h_m_pos_offset);
+ const uint32_t h_em_nan = uint32_or(h_e_mask, m_nan);
+ const uint32_t h_e_norm_overflow_offset = uint32_inc(f_e_half_bias);
+ const uint32_t h_e_norm_overflow = uint32_sll(h_e_norm_overflow_offset, h_e_pos);
+ const uint32_t h_e_norm = uint32_sll(f_e_half_bias, h_e_pos);
+ const uint32_t h_m_norm = uint32_srl(f_m_rounded, f_h_m_pos_offset);
+ const uint32_t h_em_norm = uint32_or(h_e_norm, h_m_norm);
+ const uint32_t is_h_ndenorm_msb = uint32_sub(f_h_bias_offset, f_e_amount);
+ const uint32_t is_f_e_flagged_msb = uint32_sub(f_h_e_biased_flag, f_e_half_bias);
+ const uint32_t is_h_denorm_msb = uint32_not(is_h_ndenorm_msb);
+ const uint32_t is_f_m_eqz_msb = uint32_dec(f_m);
+ const uint32_t is_h_nan_eqz_msb = uint32_dec(m_nan);
+ const uint32_t is_f_inf_msb = uint32_and(is_f_e_flagged_msb, is_f_m_eqz_msb);
+ const uint32_t is_f_nan_underflow_msb = uint32_and(is_f_e_flagged_msb, is_h_nan_eqz_msb);
+ const uint32_t is_e_overflow_msb = uint32_sub(h_e_mask_value, f_e_half_bias);
+ const uint32_t is_h_inf_msb = uint32_or(is_e_overflow_msb, is_f_inf_msb);
+ const uint32_t is_f_nsnan_msb = uint32_sub(f_snan, f_snan_mask);
+ const uint32_t is_m_norm_overflow_msb = uint32_neg(f_m_rounded_overflow);
+ const uint32_t is_f_snan_msb = uint32_not(is_f_nsnan_msb);
+ const uint32_t h_em_overflow_result = uint32_sels(is_m_norm_overflow_msb, h_e_norm_overflow, h_em_norm);
+ const uint32_t h_em_nan_result = uint32_sels(is_f_e_flagged_msb, h_em_nan, h_em_overflow_result);
+ const uint32_t h_em_nan_underflow_result = uint32_sels(is_f_nan_underflow_msb, h_nan_min, h_em_nan_result);
+ const uint32_t h_em_inf_result = uint32_sels(is_h_inf_msb, h_e_mask, h_em_nan_underflow_result);
+ const uint32_t h_em_denorm_result = uint32_sels(is_h_denorm_msb, h_m_denorm, h_em_inf_result);
+ const uint32_t h_em_snan_result = uint32_sels(is_f_snan_msb, h_snan_mask, h_em_denorm_result);
+ const uint32_t h_result = uint32_or(h_s, h_em_snan_result);
+
+ return (uint16_t)(h_result);
+ }
+
+ inline float halfToFloat(uint16_t _a)
+ {
+ const uint32_t h_e_mask = uint32_li(0x00007c00);
+ const uint32_t h_m_mask = uint32_li(0x000003ff);
+ const uint32_t h_s_mask = uint32_li(0x00008000);
+ const uint32_t h_f_s_pos_offset = uint32_li(0x00000010);
+ const uint32_t h_f_e_pos_offset = uint32_li(0x0000000d);
+ const uint32_t h_f_bias_offset = uint32_li(0x0001c000);
+ const uint32_t f_e_mask = uint32_li(0x7f800000);
+ const uint32_t f_m_mask = uint32_li(0x007fffff);
+ const uint32_t h_f_e_denorm_bias = uint32_li(0x0000007e);
+ const uint32_t h_f_m_denorm_sa_bias = uint32_li(0x00000008);
+ const uint32_t f_e_pos = uint32_li(0x00000017);
+ const uint32_t h_e_mask_minus_one = uint32_li(0x00007bff);
+ const uint32_t h_e = uint32_and(_a, h_e_mask);
+ const uint32_t h_m = uint32_and(_a, h_m_mask);
+ const uint32_t h_s = uint32_and(_a, h_s_mask);
+ const uint32_t h_e_f_bias = uint32_add(h_e, h_f_bias_offset);
+ const uint32_t h_m_nlz = uint32_cntlz(h_m);
+ const uint32_t f_s = uint32_sll(h_s, h_f_s_pos_offset);
+ const uint32_t f_e = uint32_sll(h_e_f_bias, h_f_e_pos_offset);
+ const uint32_t f_m = uint32_sll(h_m, h_f_e_pos_offset);
+ const uint32_t f_em = uint32_or(f_e, f_m);
+ const uint32_t h_f_m_sa = uint32_sub(h_m_nlz, h_f_m_denorm_sa_bias);
+ const uint32_t f_e_denorm_unpacked = uint32_sub(h_f_e_denorm_bias, h_f_m_sa);
+ const uint32_t h_f_m = uint32_sll(h_m, h_f_m_sa);
+ const uint32_t f_m_denorm = uint32_and(h_f_m, f_m_mask);
+ const uint32_t f_e_denorm = uint32_sll(f_e_denorm_unpacked, f_e_pos);
+ const uint32_t f_em_denorm = uint32_or(f_e_denorm, f_m_denorm);
+ const uint32_t f_em_nan = uint32_or(f_e_mask, f_m);
+ const uint32_t is_e_eqz_msb = uint32_dec(h_e);
+ const uint32_t is_m_nez_msb = uint32_neg(h_m);
+ const uint32_t is_e_flagged_msb = uint32_sub(h_e_mask_minus_one, h_e);
+ const uint32_t is_zero_msb = uint32_andc(is_e_eqz_msb, is_m_nez_msb);
+ const uint32_t is_inf_msb = uint32_andc(is_e_flagged_msb, is_m_nez_msb);
+ const uint32_t is_denorm_msb = uint32_and(is_m_nez_msb, is_e_eqz_msb);
+ const uint32_t is_nan_msb = uint32_and(is_e_flagged_msb, is_m_nez_msb);
+ const uint32_t is_zero = uint32_ext(is_zero_msb);
+ const uint32_t f_zero_result = uint32_andc(f_em, is_zero);
+ const uint32_t f_denorm_result = uint32_sels(is_denorm_msb, f_em_denorm, f_zero_result);
+ const uint32_t f_inf_result = uint32_sels(is_inf_msb, f_e_mask, f_denorm_result);
+ const uint32_t f_nan_result = uint32_sels(is_nan_msb, f_em_nan, f_inf_result);
+ const uint32_t f_result = uint32_or(f_s, f_nan_result);
+
+ union { uint32_t ui; float flt; } utof;
+ utof.ui = f_result;
+ return utof.flt;
+ }
+
+ inline uint16_t uint16_min(uint16_t _a, uint16_t _b)
+ {
+ return _a > _b ? _b : _a;
+ }
+
+ inline uint16_t uint16_max(uint16_t _a, uint16_t _b)
+ {
+ return _a < _b ? _b : _a;
+ }
+
+ inline int64_t int64_min(int64_t _a, int64_t _b)
+ {
+ return _a < _b ? _a : _b;
+ }
+
+ inline int64_t int64_max(int64_t _a, int64_t _b)
+ {
+ return _a > _b ? _a : _b;
+ }
+
+ inline int64_t int64_clamp(int64_t _a, int64_t _min, int64_t _max)
+ {
+ const int64_t min = int64_min(_a, _max);
+ const int64_t result = int64_max(_min, min);
+
+ return result;
+ }
+
+ inline uint32_t uint64_cntbits_ref(uint64_t _val)
+ {
+ const uint32_t lo = uint32_t(_val&UINT32_MAX);
+ const uint32_t hi = uint32_t(_val>>32);
+
+ const uint32_t total = bx::uint32_cntbits(lo)
+ + bx::uint32_cntbits(hi);
+ return total;
+ }
+
+ /// Count number of bits set.
+ inline uint32_t uint64_cntbits(uint64_t _val)
+ {
+#if BX_COMPILER_GCC || BX_COMPILER_CLANG
+ return __builtin_popcountll(_val);
+#elif BX_COMPILER_MSVC && BX_ARCH_64BIT
+ return uint32_t(__popcnt64(_val) );
+#else
+ return uint64_cntbits_ref(_val);
+#endif // BX_COMPILER_
+ }
+
+ inline uint32_t uint64_cntlz_ref(uint64_t _val)
+ {
+ return _val & UINT64_C(0xffffffff00000000)
+ ? uint32_cntlz(uint32_t(_val>>32) )
+ : uint32_cntlz(uint32_t(_val) ) + 32
+ ;
+ }
+
+ /// Count number of leading zeros.
+ inline uint32_t uint64_cntlz(uint64_t _val)
+ {
+#if BX_COMPILER_GCC || BX_COMPILER_CLANG
+ return __builtin_clzll(_val);
+#elif BX_COMPILER_MSVC && BX_PLATFORM_WINDOWS && BX_ARCH_64BIT
+ unsigned long index;
+ _BitScanReverse64(&index, _val);
+ return uint32_t(63 - index);
+#else
+ return uint64_cntlz_ref(_val);
+#endif // BX_COMPILER_
+ }
+
+ inline uint32_t uint64_cnttz_ref(uint64_t _val)
+ {
+ return _val & UINT64_C(0xffffffff)
+ ? uint32_cnttz(uint32_t(_val) )
+ : uint32_cnttz(uint32_t(_val>>32) ) + 32
+ ;
+ }
+
+ inline uint32_t uint64_cnttz(uint64_t _val)
+ {
+#if BX_COMPILER_GCC || BX_COMPILER_CLANG
+ return __builtin_ctzll(_val);
+#elif BX_COMPILER_MSVC && BX_PLATFORM_WINDOWS && BX_ARCH_64BIT
+ unsigned long index;
+ _BitScanForward64(&index, _val);
+ return uint32_t(index);
+#else
+ return uint64_cnttz_ref(_val);
+#endif // BX_COMPILER_
+ }
+
+ inline uint64_t uint64_sll(uint64_t _a, int _sa)
+ {
+ return _a << _sa;
+ }
+
+ inline uint64_t uint64_srl(uint64_t _a, int _sa)
+ {
+ return _a >> _sa;
+ }
+
+ inline uint64_t uint64_sra(uint64_t _a, int _sa)
+ {
+ return ( (int64_t)_a) >> _sa;
+ }
+
+ inline uint64_t uint64_rol(uint64_t _a, int _sa)
+ {
+ return ( _a << _sa) | (_a >> (32-_sa) );
+ }
+
+ inline uint64_t uint64_ror(uint64_t _a, int _sa)
+ {
+ return ( _a >> _sa) | (_a << (32-_sa) );
+ }
+
+ inline uint64_t uint64_add(uint64_t _a, uint64_t _b)
+ {
+ return _a + _b;
+ }
+
+ inline uint64_t uint64_sub(uint64_t _a, uint64_t _b)
+ {
+ return _a - _b;
+ }
+
+ inline uint64_t uint64_mul(uint64_t _a, uint64_t _b)
+ {
+ return _a * _b;
+ }
+
+ /// Greatest common divisor.
+ inline uint32_t uint32_gcd(uint32_t _a, uint32_t _b)
+ {
+ do
+ {
+ uint32_t tmp = _a % _b;
+ _a = _b;
+ _b = tmp;
+ }
+ while (_b);
+
+ return _a;
+ }
+
+ /// Least common multiple.
+ inline uint32_t uint32_lcm(uint32_t _a, uint32_t _b)
+ {
+ return _a * (_b / uint32_gcd(_a, _b) );
+ }
+
+ /// Align to arbitrary stride.
+ inline uint32_t strideAlign(uint32_t _offset, uint32_t _stride)
+ {
+ const uint32_t mod = uint32_mod(_offset, _stride);
+ const uint32_t add = uint32_sub(_stride, mod);
+ const uint32_t mask = uint32_cmpeq(mod, 0);
+ const uint32_t tmp = uint32_selb(mask, 0, add);
+ const uint32_t result = uint32_add(_offset, tmp);
+
+ return result;
+ }
+
+ /// Align to arbitrary stride and 16-bytes.
+ inline uint32_t strideAlign16(uint32_t _offset, uint32_t _stride)
+ {
+ const uint32_t align = uint32_lcm(16, _stride);
+ const uint32_t mod = uint32_mod(_offset, align);
+ const uint32_t mask = uint32_cmpeq(mod, 0);
+ const uint32_t tmp0 = uint32_selb(mask, 0, align);
+ const uint32_t tmp1 = uint32_add(_offset, tmp0);
+ const uint32_t result = uint32_sub(tmp1, mod);
+
+ return result;
+ }
+
+ /// Align to arbitrary stride and 256-bytes.
+ inline uint32_t strideAlign256(uint32_t _offset, uint32_t _stride)
+ {
+ const uint32_t align = uint32_lcm(256, _stride);
+ const uint32_t mod = uint32_mod(_offset, align);
+ const uint32_t mask = uint32_cmpeq(mod, 0);
+ const uint32_t tmp0 = uint32_selb(mask, 0, align);
+ const uint32_t tmp1 = uint32_add(_offset, tmp0);
+ const uint32_t result = uint32_sub(tmp1, mod);
+
+ return result;
+ }
+
+} // namespace bx
diff --git a/3rdparty/bx/makefile b/3rdparty/bx/makefile
index 6a6598f80b1..bf8d91167d2 100644
--- a/3rdparty/bx/makefile
+++ b/3rdparty/bx/makefile
@@ -1,6 +1,6 @@
#
-# Copyright 2011-2015 Branimir Karadzic. All rights reserved.
-# License: http://www.opensource.org/licenses/BSD-2-Clause
+# Copyright 2011-2017 Branimir Karadzic. All rights reserved.
+# License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
#
GENIE=../bx/tools/bin/$(OS)/genie
diff --git a/3rdparty/bx/scripts/bin2c.lua b/3rdparty/bx/scripts/bin2c.lua
index 5dbc29d7b14..b308b3eb253 100644
--- a/3rdparty/bx/scripts/bin2c.lua
+++ b/3rdparty/bx/scripts/bin2c.lua
@@ -16,6 +16,10 @@ project "bin2c"
"../tools/bin2c/**.h",
}
+ links {
+ "bx",
+ }
+
configuration { "mingw-*" }
targetextension ".exe"
diff --git a/3rdparty/bx/scripts/bx.lua b/3rdparty/bx/scripts/bx.lua
index 2f1e4e57585..b62ee4bae5f 100644
--- a/3rdparty/bx/scripts/bx.lua
+++ b/3rdparty/bx/scripts/bx.lua
@@ -2,24 +2,23 @@
-- Copyright 2010-2017 Branimir Karadzic. All rights reserved.
-- License: https://github.com/bkaradzic/bx#license-bsd-2-clause
--
-
+
project "bx"
- uuid "4db0b09e-d6df-11e1-a0ec-65ccdd6a022f"
kind "StaticLib"
- configuration { "osx or ios" }
- -- OSX ar doesn't like creating archive without object files
- -- here is object file...
- prebuildcommands {
- "@echo \"void dummy() {}\" > /tmp/dummy.cpp",
- }
- files {
- "/tmp/dummy.cpp",
- }
-
- configuration {}
+ includedirs {
+ "../include",
+ }
files {
"../include/**.h",
"../include/**.inl",
+ "../src/**.cpp",
}
+
+ configuration { "linux-*" }
+ buildoptions {
+ "-fPIC",
+ }
+
+ configuration {}
diff --git a/3rdparty/bx/scripts/genie.lua b/3rdparty/bx/scripts/genie.lua
index 1e8f9028010..e0e634ae716 100644
--- a/3rdparty/bx/scripts/genie.lua
+++ b/3rdparty/bx/scripts/genie.lua
@@ -54,6 +54,10 @@ project "bx.test"
path.join(BX_DIR, "tests/dbg.*"),
}
+ links {
+ "bx",
+ }
+
configuration { "vs* or mingw*" }
links {
"psapi",
@@ -109,6 +113,10 @@ project "bx.bench"
path.join(BX_DIR, "tests/dbg.*"),
}
+ links {
+ "bx",
+ }
+
configuration { "vs* or mingw*" }
links {
"psapi",
diff --git a/3rdparty/bx/scripts/toolchain.lua b/3rdparty/bx/scripts/toolchain.lua
index 5d8573a690e..6a01c92422c 100644
--- a/3rdparty/bx/scripts/toolchain.lua
+++ b/3rdparty/bx/scripts/toolchain.lua
@@ -532,21 +532,27 @@ function toolchain(_buildDir, _libDir)
"__STDC_CONSTANT_MACROS",
}
- configuration { "qbs" }
- flags {
- "ExtraWarnings",
- }
-
configuration { "Debug" }
targetsuffix "Debug"
+ defines {
+ "_DEBUG",
+ }
configuration { "Release" }
flags {
"NoBufferSecurityCheck",
"OptimizeSpeed",
}
+ defines {
+ "NDEBUG",
+ }
targetsuffix "Release"
+ configuration { "qbs" }
+ flags {
+ "ExtraWarnings",
+ }
+
configuration { "vs*", "x32" }
flags {
"EnableSSE2",
diff --git a/3rdparty/bx/src/commandline.cpp b/3rdparty/bx/src/commandline.cpp
new file mode 100644
index 00000000000..400e4965a0e
--- /dev/null
+++ b/3rdparty/bx/src/commandline.cpp
@@ -0,0 +1,322 @@
+/*
+ * Copyright 2010-2017 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ */
+
+#include <bx/commandline.h>
+#include <bx/string.h>
+
+namespace bx
+{
+ // Reference:
+ // http://msdn.microsoft.com/en-us/library/a1y7w461.aspx
+ const char* tokenizeCommandLine(const char* _commandLine, char* _buffer, uint32_t& _bufferSize, int32_t& _argc, char* _argv[], int32_t _maxArgvs, char _term)
+ {
+ int32_t argc = 0;
+ const char* curr = _commandLine;
+ char* currOut = _buffer;
+ char term = ' ';
+ bool sub = false;
+
+ enum ParserState
+ {
+ SkipWhitespace,
+ SetTerm,
+ Copy,
+ Escape,
+ End,
+ };
+
+ ParserState state = SkipWhitespace;
+
+ while ('\0' != *curr
+ && _term != *curr
+ && argc < _maxArgvs)
+ {
+ switch (state)
+ {
+ case SkipWhitespace:
+ for (; isSpace(*curr); ++curr) {}; // skip whitespace
+ state = SetTerm;
+ break;
+
+ case SetTerm:
+ if ('"' == *curr)
+ {
+ term = '"';
+ ++curr; // skip begining quote
+ }
+ else
+ {
+ term = ' ';
+ }
+
+ _argv[argc] = currOut;
+ ++argc;
+
+ state = Copy;
+ break;
+
+ case Copy:
+ if ('\\' == *curr)
+ {
+ state = Escape;
+ }
+ else if ('"' == *curr
+ && '"' != term)
+ {
+ sub = !sub;
+ }
+ else if (isSpace(*curr) && !sub)
+ {
+ state = End;
+ }
+ else if (term != *curr || sub)
+ {
+ *currOut = *curr;
+ ++currOut;
+ }
+ else
+ {
+ state = End;
+ }
+ ++curr;
+ break;
+
+ case Escape:
+ {
+ const char* start = --curr;
+ for (; '\\' == *curr; ++curr) {};
+
+ if ('"' != *curr)
+ {
+ int32_t count = (int32_t)(curr-start);
+
+ curr = start;
+ for (int32_t ii = 0; ii < count; ++ii)
+ {
+ *currOut = *curr;
+ ++currOut;
+ ++curr;
+ }
+ }
+ else
+ {
+ curr = start+1;
+ *currOut = *curr;
+ ++currOut;
+ ++curr;
+ }
+ }
+ state = Copy;
+ break;
+
+ case End:
+ *currOut = '\0';
+ ++currOut;
+ state = SkipWhitespace;
+ break;
+ }
+ }
+
+ *currOut = '\0';
+ if (0 < argc
+ && '\0' == _argv[argc-1][0])
+ {
+ --argc;
+ }
+
+ _bufferSize = (uint32_t)(currOut - _buffer);
+ _argc = argc;
+
+ if ('\0' != *curr)
+ {
+ ++curr;
+ }
+
+ return curr;
+ }
+
+ CommandLine::CommandLine(int32_t _argc, char const* const* _argv)
+ : m_argc(_argc)
+ , m_argv(_argv)
+ {
+ }
+
+ const char* CommandLine::findOption(const char* _long, const char* _default) const
+ {
+ const char* result = find(0, '\0', _long, 1);
+ return result == NULL ? _default : result;
+ }
+
+ const char* CommandLine::findOption(const char _short, const char* _long, const char* _default) const
+ {
+ const char* result = find(0, _short, _long, 1);
+ return result == NULL ? _default : result;
+ }
+
+ const char* CommandLine::findOption(const char* _long, int32_t _numParams) const
+ {
+ const char* result = find(0, '\0', _long, _numParams);
+ return result;
+ }
+
+ const char* CommandLine::findOption(const char _short, const char* _long, int32_t _numParams) const
+ {
+ const char* result = find(0, _short, _long, _numParams);
+ return result;
+ }
+
+ const char* CommandLine::findOption(int32_t _skip, const char _short, const char* _long, int32_t _numParams) const
+ {
+ const char* result = find(_skip, _short, _long, _numParams);
+ return result;
+ }
+
+ bool CommandLine::hasArg(const char _short, const char* _long) const
+ {
+ const char* arg = findOption(_short, _long, 0);
+ return NULL != arg;
+ }
+
+ bool CommandLine::hasArg(const char* _long) const
+ {
+ const char* arg = findOption('\0', _long, 0);
+ return NULL != arg;
+ }
+
+ bool CommandLine::hasArg(const char*& _value, const char _short, const char* _long) const
+ {
+ const char* arg = findOption(_short, _long, 1);
+ _value = arg;
+ return NULL != arg;
+ }
+
+ bool CommandLine::hasArg(int32_t& _value, const char _short, const char* _long) const
+ {
+ const char* arg = findOption(_short, _long, 1);
+ if (NULL != arg)
+ {
+ _value = atoi(arg);
+ return true;
+ }
+
+ return false;
+ }
+
+ bool CommandLine::hasArg(uint32_t& _value, const char _short, const char* _long) const
+ {
+ const char* arg = findOption(_short, _long, 1);
+ if (NULL != arg)
+ {
+ _value = atoi(arg);
+ return true;
+ }
+
+ return false;
+ }
+
+ bool CommandLine::hasArg(float& _value, const char _short, const char* _long) const
+ {
+ const char* arg = findOption(_short, _long, 1);
+ if (NULL != arg)
+ {
+ _value = float(atof(arg));
+ return true;
+ }
+
+ return false;
+ }
+
+ bool CommandLine::hasArg(double& _value, const char _short, const char* _long) const
+ {
+ const char* arg = findOption(_short, _long, 1);
+ if (NULL != arg)
+ {
+ _value = atof(arg);
+ return true;
+ }
+
+ return false;
+ }
+
+ bool CommandLine::hasArg(bool& _value, const char _short, const char* _long) const
+ {
+ const char* arg = findOption(_short, _long, 1);
+ if (NULL != arg)
+ {
+ if ('0' == *arg || (0 == strincmp(arg, "false") ) )
+ {
+ _value = false;
+ }
+ else if ('0' != *arg || (0 == strincmp(arg, "true") ) )
+ {
+ _value = true;
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ const char* CommandLine::find(int32_t _skip, const char _short, const char* _long, int32_t _numParams) const
+ {
+ for (int32_t ii = 0; ii < m_argc; ++ii)
+ {
+ const char* arg = m_argv[ii];
+ if ('-' == *arg)
+ {
+ ++arg;
+ if (_short == *arg)
+ {
+ if (1 == strnlen(arg) )
+ {
+ if (0 == _skip)
+ {
+ if (0 == _numParams)
+ {
+ return "";
+ }
+ else if (ii+_numParams < m_argc
+ && '-' != *m_argv[ii+1] )
+ {
+ return m_argv[ii+1];
+ }
+
+ return NULL;
+ }
+
+ --_skip;
+ ii += _numParams;
+ }
+ }
+ else if (NULL != _long
+ && '-' == *arg
+ && 0 == strincmp(arg+1, _long) )
+ {
+ if (0 == _skip)
+ {
+ if (0 == _numParams)
+ {
+ return "";
+ }
+ else if (ii+_numParams < m_argc
+ && '-' != *m_argv[ii+1] )
+ {
+ return m_argv[ii+1];
+ }
+
+ return NULL;
+ }
+
+ --_skip;
+ ii += _numParams;
+ }
+ }
+ }
+
+ return NULL;
+ }
+
+} // namespace bx
diff --git a/3rdparty/bx/src/crt.cpp b/3rdparty/bx/src/crt.cpp
new file mode 100644
index 00000000000..8686f03d267
--- /dev/null
+++ b/3rdparty/bx/src/crt.cpp
@@ -0,0 +1,362 @@
+/*
+ * Copyright 2010-2017 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ */
+
+#include <bx/bx.h>
+#include <bx/readerwriter.h>
+#include <bx/debug.h>
+
+namespace bx
+{
+ void* memCopyRef(void* _dst, const void* _src, size_t _numBytes)
+ {
+ uint8_t* dst = (uint8_t*)_dst;
+ const uint8_t* end = dst + _numBytes;
+ const uint8_t* src = (const uint8_t*)_src;
+ while (dst != end)
+ {
+ *dst++ = *src++;
+ }
+
+ return _dst;
+ }
+
+ void* memCopy(void* _dst, const void* _src, size_t _numBytes)
+ {
+#if BX_CRT_NONE
+ return memCopyRef(_dst, _src, _numBytes);
+#else
+ return ::memcpy(_dst, _src, _numBytes);
+#endif // BX_CRT_NONE
+ }
+
+ void memCopy(void* _dst, const void* _src, uint32_t _size, uint32_t _num, uint32_t _srcPitch, uint32_t _dstPitch)
+ {
+ const uint8_t* src = (const uint8_t*)_src;
+ uint8_t* dst = (uint8_t*)_dst;
+
+ for (uint32_t ii = 0; ii < _num; ++ii)
+ {
+ memCopy(dst, src, _size);
+ src += _srcPitch;
+ dst += _dstPitch;
+ }
+ }
+
+ ///
+ void gather(void* _dst, const void* _src, uint32_t _size, uint32_t _num, uint32_t _srcPitch)
+ {
+ memCopy(_dst, _src, _size, _num, _srcPitch, _size);
+ }
+
+ ///
+ void scatter(void* _dst, const void* _src, uint32_t _size, uint32_t _num, uint32_t _dstPitch)
+ {
+ memCopy(_dst, _src, _size, _num, _size, _dstPitch);
+ }
+
+ void* memMoveRef(void* _dst, const void* _src, size_t _numBytes)
+ {
+ uint8_t* dst = (uint8_t*)_dst;
+ const uint8_t* src = (const uint8_t*)_src;
+
+ if (_numBytes == 0
+ || dst == src)
+ {
+ return dst;
+ }
+
+ // if (src+_numBytes <= dst || end <= src)
+ if (dst < src)
+ {
+ return memcpy(_dst, _src, _numBytes);
+ }
+
+ for (intptr_t ii = _numBytes-1; ii >= 0; --ii)
+ {
+ dst[ii] = src[ii];
+ }
+
+ return _dst;
+ }
+
+ void* memMove(void* _dst, const void* _src, size_t _numBytes)
+ {
+#if BX_CRT_NONE
+ return memMoveRef(_dst, _src, _numBytes);
+#else
+ return ::memmove(_dst, _src, _numBytes);
+#endif // BX_CRT_NONE
+ }
+
+ void* memSetRef(void* _dst, uint8_t _ch, size_t _numBytes)
+ {
+ uint8_t* dst = (uint8_t*)_dst;
+ const uint8_t* end = dst + _numBytes;
+ while (dst != end)
+ {
+ *dst++ = char(_ch);
+ }
+
+ return _dst;
+ }
+
+ void* memSet(void* _dst, uint8_t _ch, size_t _numBytes)
+ {
+#if BX_CRT_NONE
+ return memSetRef(_dst, _ch, _numBytes);
+#else
+ return ::memset(_dst, _ch, _numBytes);
+#endif // BX_CRT_NONE
+ }
+
+ namespace
+ {
+ struct Param
+ {
+ int32_t width;
+ uint32_t base;
+ uint32_t prec;
+ char fill;
+ bool left;
+ };
+
+ static int32_t write(WriterI* _writer, const char* _str, int32_t _len, const Param& _param, Error* _err)
+ {
+ int32_t size = 0;
+ int32_t len = (int32_t)strnlen(_str, _len);
+ int32_t padding = _param.width > len ? _param.width - len : 0;
+
+ if (!_param.left)
+ {
+ size += writeRep(_writer, _param.fill, padding, _err);
+ }
+
+ size += write(_writer, _str, len, _err);
+
+ if (_param.left)
+ {
+ size += writeRep(_writer, _param.fill, padding, _err);
+ }
+
+ return size;
+ }
+
+ static int32_t write(WriterI* _writer, const char* _str, const Param& _param, Error* _err)
+ {
+ return write(_writer, _str, INT32_MAX, _param, _err);
+ }
+
+ static int32_t write(WriterI* _writer, int32_t _i, const Param& _param, Error* _err)
+ {
+ char str[33];
+ int32_t len = toString(str, sizeof(str), _i, _param.base);
+
+ if (len == 0)
+ {
+ return 0;
+ }
+
+ return write(_writer, str, len, _param, _err);
+ }
+
+ static int32_t write(WriterI* _writer, uint32_t _i, const Param& _param, Error* _err)
+ {
+ char str[33];
+ int32_t len = toString(str, sizeof(str), _i, _param.base);
+
+ if (len == 0)
+ {
+ return 0;
+ }
+
+ return write(_writer, str, len, _param, _err);
+ }
+
+ static int32_t write(WriterI* _writer, double _d, const Param& _param, Error* _err)
+ {
+ char str[1024];
+ int32_t len = toString(str, sizeof(str), _d);
+
+ if (len == 0)
+ {
+ return 0;
+ }
+
+ const char* dot = strnchr(str, '.');
+ const int32_t precLen = int32_t(dot + 1 + _param.prec - str);
+ if (precLen > len)
+ {
+ for (int32_t ii = len; ii < precLen; ++ii)
+ {
+ str[ii] = '0';
+ }
+ str[precLen] = '\0';
+ }
+ len = precLen;
+
+ return write(_writer, str, len, _param, _err);
+ }
+
+ static int32_t write(WriterI* _writer, const void* _ptr, const Param& _param, Error* _err)
+ {
+ char str[35] = "0x";
+ int32_t len = toString(str + 2, sizeof(str) - 2, uint32_t(uintptr_t(_ptr) ), 16);
+
+ if (len == 0)
+ {
+ return 0;
+ }
+
+ len += 2;
+ return write(_writer, str, len, _param, _err);
+ }
+ } // anonymous namespace
+
+ int32_t write(WriterI* _writer, const char* _format, va_list _argList, Error* _err)
+ {
+ MemoryReader reader(_format, strnlen(_format) );
+
+ int32_t size = 0;
+
+ while (_err->isOk() )
+ {
+ char ch = '\0';
+ read(&reader, ch, _err);
+
+ if (!_err->isOk() )
+ {
+ break;
+ }
+ else if ('%' == ch)
+ {
+ // %[ -0][<width>][.<precision>]
+ read(&reader, ch);
+
+ Param param;
+ param.base = 10;
+ param.prec = 6;
+ param.left = false;
+ param.fill = ' ';
+ param.width = 0;
+
+ while (' ' == ch
+ || '-' == ch
+ || '0' == ch)
+ {
+ switch (ch)
+ {
+ case '-': param.left = true; break;
+ case ' ': param.fill = ' '; break;
+ case '0': param.fill = '0'; break;
+ }
+
+ if (param.left)
+ {
+ param.fill = ' ';
+ }
+
+ read(&reader, ch);
+ }
+
+ if ('*' == ch)
+ {
+ read(&reader, ch);
+ param.width = va_arg(_argList, int32_t);
+
+ if (0 > param.width)
+ {
+ param.left = true;
+ param.width = -param.width;
+ }
+
+ }
+ else
+ {
+ while (isNumeric(ch) )
+ {
+ param.width = param.width * 10 + ch - '0';
+ read(&reader, ch);
+ }
+ }
+
+ if ('.' == ch)
+ {
+ read(&reader, ch);
+
+ if ('*' == ch)
+ {
+ read(&reader, ch);
+ param.prec = va_arg(_argList, int32_t);
+ }
+ else
+ {
+ param.prec = 0;
+ while (isNumeric(ch) )
+ {
+ param.prec = param.prec * 10 + ch - '0';
+ read(&reader, ch);
+ }
+ }
+ }
+
+ switch (toLower(ch) )
+ {
+ case 'c':
+ size += write(_writer, char(va_arg(_argList, int32_t) ), _err);
+ break;
+
+ case 's':
+ size += write(_writer, va_arg(_argList, const char*), param, _err);
+ break;
+
+ case 'd':
+ param.base = 10;
+ size += write(_writer, va_arg(_argList, int32_t), param, _err);
+ break;
+
+ case 'f':
+ size += write(_writer, va_arg(_argList, double), param, _err);
+ break;
+
+ case 'p':
+ size += write(_writer, va_arg(_argList, void*), param, _err);
+ break;
+
+ case 'x':
+ param.base = 16;
+ size += write(_writer, va_arg(_argList, uint32_t), param, _err);
+ break;
+
+ case 'u':
+ param.base = 10;
+ size += write(_writer, va_arg(_argList, uint32_t), param, _err);
+ break;
+
+ default:
+ size += write(_writer, ch, _err);
+ break;
+ }
+ }
+ else
+ {
+ size += write(_writer, ch, _err);
+ }
+ }
+
+ size += write(_writer, '\0', _err);
+
+ return size;
+ }
+
+ int32_t write(WriterI* _writer, Error* _err, const char* _format, ...)
+ {
+ va_list argList;
+ va_start(argList, _format);
+ int32_t size = write(_writer, _format, argList, _err);
+ va_end(argList);
+ return size;
+ }
+
+} // namespace bx
diff --git a/3rdparty/bx/src/crtimpl.cpp b/3rdparty/bx/src/crtimpl.cpp
new file mode 100644
index 00000000000..7adb74bb8ee
--- /dev/null
+++ b/3rdparty/bx/src/crtimpl.cpp
@@ -0,0 +1,360 @@
+/*
+ * Copyright 2010-2017 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ */
+
+#include <bx/crtimpl.h>
+
+#if BX_CONFIG_ALLOCATOR_CRT
+# include <malloc.h>
+#endif // BX_CONFIG_ALLOCATOR_CRT
+
+namespace bx
+{
+#if BX_CONFIG_ALLOCATOR_CRT
+ CrtAllocator::CrtAllocator()
+ {
+ }
+
+ CrtAllocator::~CrtAllocator()
+ {
+ }
+
+ void* CrtAllocator::realloc(void* _ptr, size_t _size, size_t _align, const char* _file, uint32_t _line)
+ {
+ if (0 == _size)
+ {
+ if (NULL != _ptr)
+ {
+ if (BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT >= _align)
+ {
+ ::free(_ptr);
+ return NULL;
+ }
+
+# if BX_COMPILER_MSVC
+ BX_UNUSED(_file, _line);
+ _aligned_free(_ptr);
+# else
+ bx::alignedFree(this, _ptr, _align, _file, _line);
+# endif // BX_
+ }
+
+ return NULL;
+ }
+ else if (NULL == _ptr)
+ {
+ if (BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT >= _align)
+ {
+ return ::malloc(_size);
+ }
+
+# if BX_COMPILER_MSVC
+ BX_UNUSED(_file, _line);
+ return _aligned_malloc(_size, _align);
+# else
+ return bx::alignedAlloc(this, _size, _align, _file, _line);
+# endif // BX_
+ }
+
+ if (BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT >= _align)
+ {
+ return ::realloc(_ptr, _size);
+ }
+
+# if BX_COMPILER_MSVC
+ BX_UNUSED(_file, _line);
+ return _aligned_realloc(_ptr, _size, _align);
+# else
+ return bx::alignedRealloc(this, _ptr, _size, _align, _file, _line);
+# endif // BX_
+ }
+#endif // BX_CONFIG_ALLOCATOR_CRT
+
+#if BX_CONFIG_CRT_FILE_READER_WRITER
+
+# if BX_CRT_MSVC
+# define fseeko64 _fseeki64
+# define ftello64 _ftelli64
+# elif 0 \
+ || BX_PLATFORM_ANDROID \
+ || BX_PLATFORM_BSD \
+ || BX_PLATFORM_IOS \
+ || BX_PLATFORM_OSX \
+ || BX_PLATFORM_QNX
+# define fseeko64 fseeko
+# define ftello64 ftello
+# elif BX_PLATFORM_PS4
+# define fseeko64 fseek
+# define ftello64 ftell
+# endif // BX_
+
+ CrtFileReader::CrtFileReader()
+ : m_file(NULL)
+ {
+ }
+
+ CrtFileReader::~CrtFileReader()
+ {
+ }
+
+ bool CrtFileReader::open(const char* _filePath, Error* _err)
+ {
+ BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
+
+ if (NULL != m_file)
+ {
+ BX_ERROR_SET(_err, BX_ERROR_READERWRITER_ALREADY_OPEN, "CrtFileReader: File is already open.");
+ return false;
+ }
+
+ m_file = fopen(_filePath, "rb");
+ if (NULL == m_file)
+ {
+ BX_ERROR_SET(_err, BX_ERROR_READERWRITER_OPEN, "CrtFileReader: Failed to open file.");
+ return false;
+ }
+
+ return true;
+ }
+
+ void CrtFileReader::close()
+ {
+ BX_CHECK(NULL != m_file, "Reader/Writer file is not open.");
+ FILE* file = (FILE*)m_file;
+ fclose(file);
+ m_file = NULL;
+ }
+
+ int64_t CrtFileReader::seek(int64_t _offset, Whence::Enum _whence)
+ {
+ BX_CHECK(NULL != m_file, "Reader/Writer file is not open.");
+ FILE* file = (FILE*)m_file;
+ fseeko64(file, _offset, _whence);
+ return ftello64(file);
+ }
+
+ int32_t CrtFileReader::read(void* _data, int32_t _size, Error* _err)
+ {
+ BX_CHECK(NULL != m_file, "Reader/Writer file is not open.");
+ BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
+
+ FILE* file = (FILE*)m_file;
+ int32_t size = (int32_t)fread(_data, 1, _size, file);
+ if (size != _size)
+ {
+ if (0 != feof(file) )
+ {
+ BX_ERROR_SET(_err, BX_ERROR_READERWRITER_EOF, "CrtFileReader: EOF.");
+ }
+ else if (0 != ferror(file) )
+ {
+ BX_ERROR_SET(_err, BX_ERROR_READERWRITER_READ, "CrtFileReader: read error.");
+ }
+
+ return size >= 0 ? size : 0;
+ }
+
+ return size;
+ }
+
+ CrtFileWriter::CrtFileWriter()
+ : m_file(NULL)
+ {
+ }
+
+ CrtFileWriter::~CrtFileWriter()
+ {
+ }
+
+ bool CrtFileWriter::open(const char* _filePath, bool _append, Error* _err)
+ {
+ BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
+
+ if (NULL != m_file)
+ {
+ BX_ERROR_SET(_err, BX_ERROR_READERWRITER_ALREADY_OPEN, "CrtFileReader: File is already open.");
+ return false;
+ }
+
+ m_file = fopen(_filePath, _append ? "ab" : "wb");
+
+ if (NULL == m_file)
+ {
+ BX_ERROR_SET(_err, BX_ERROR_READERWRITER_OPEN, "CrtFileWriter: Failed to open file.");
+ return false;
+ }
+
+ return true;
+ }
+
+ void CrtFileWriter::close()
+ {
+ BX_CHECK(NULL != m_file, "Reader/Writer file is not open.");
+ FILE* file = (FILE*)m_file;
+ fclose(file);
+ m_file = NULL;
+ }
+
+ int64_t CrtFileWriter::seek(int64_t _offset, Whence::Enum _whence)
+ {
+ BX_CHECK(NULL != m_file, "Reader/Writer file is not open.");
+ FILE* file = (FILE*)m_file;
+ fseeko64(file, _offset, _whence);
+ return ftello64(file);
+ }
+
+ int32_t CrtFileWriter::write(const void* _data, int32_t _size, Error* _err)
+ {
+ BX_CHECK(NULL != m_file, "Reader/Writer file is not open.");
+ BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
+
+ FILE* file = (FILE*)m_file;
+ int32_t size = (int32_t)fwrite(_data, 1, _size, file);
+ if (size != _size)
+ {
+ BX_ERROR_SET(_err, BX_ERROR_READERWRITER_WRITE, "CrtFileWriter: write failed.");
+ return size >= 0 ? size : 0;
+ }
+
+ return size;
+ }
+#endif // BX_CONFIG_CRT_FILE_READER_WRITER
+
+#if BX_CONFIG_CRT_PROCESS
+
+#if BX_CRT_MSVC
+# define popen _popen
+# define pclose _pclose
+#endif // BX_CRT_MSVC
+
+ ProcessReader::ProcessReader()
+ : m_file(NULL)
+ {
+ }
+
+ ProcessReader::~ProcessReader()
+ {
+ BX_CHECK(NULL == m_file, "Process not closed!");
+ }
+
+ bool ProcessReader::open(const char* _command, Error* _err)
+ {
+ BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
+
+ if (NULL != m_file)
+ {
+ BX_ERROR_SET(_err, BX_ERROR_READERWRITER_ALREADY_OPEN, "ProcessReader: File is already open.");
+ return false;
+ }
+
+ m_file = popen(_command, "r");
+ if (NULL == m_file)
+ {
+ BX_ERROR_SET(_err, BX_ERROR_READERWRITER_OPEN, "ProcessReader: Failed to open process.");
+ return false;
+ }
+
+ return true;
+ }
+
+ void ProcessReader::close()
+ {
+ BX_CHECK(NULL != m_file, "Process not open!");
+ FILE* file = (FILE*)m_file;
+ m_exitCode = pclose(file);
+ m_file = NULL;
+ }
+
+ int32_t ProcessReader::read(void* _data, int32_t _size, Error* _err)
+ {
+ BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); BX_UNUSED(_err);
+
+ FILE* file = (FILE*)m_file;
+ int32_t size = (int32_t)fread(_data, 1, _size, file);
+ if (size != _size)
+ {
+ if (0 != feof(file) )
+ {
+ BX_ERROR_SET(_err, BX_ERROR_READERWRITER_EOF, "ProcessReader: EOF.");
+ }
+ else if (0 != ferror(file) )
+ {
+ BX_ERROR_SET(_err, BX_ERROR_READERWRITER_READ, "ProcessReader: read error.");
+ }
+
+ return size >= 0 ? size : 0;
+ }
+
+ return size;
+ }
+
+ int32_t ProcessReader::getExitCode() const
+ {
+ return m_exitCode;
+ }
+
+ ProcessWriter::ProcessWriter()
+ : m_file(NULL)
+ {
+ }
+
+ ProcessWriter::~ProcessWriter()
+ {
+ BX_CHECK(NULL == m_file, "Process not closed!");
+ }
+
+ bool ProcessWriter::open(const char* _command, bool, Error* _err)
+ {
+ BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
+
+ if (NULL != m_file)
+ {
+ BX_ERROR_SET(_err, BX_ERROR_READERWRITER_ALREADY_OPEN, "ProcessWriter: File is already open.");
+ return false;
+ }
+
+ m_file = popen(_command, "w");
+ if (NULL == m_file)
+ {
+ BX_ERROR_SET(_err, BX_ERROR_READERWRITER_OPEN, "ProcessWriter: Failed to open process.");
+ return false;
+ }
+
+ return true;
+ }
+
+ void ProcessWriter::close()
+ {
+ BX_CHECK(NULL != m_file, "Process not open!");
+ FILE* file = (FILE*)m_file;
+ m_exitCode = pclose(file);
+ m_file = NULL;
+ }
+
+ int32_t ProcessWriter::write(const void* _data, int32_t _size, Error* _err)
+ {
+ BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); BX_UNUSED(_err);
+
+ FILE* file = (FILE*)m_file;
+ int32_t size = (int32_t)fwrite(_data, 1, _size, file);
+ if (size != _size)
+ {
+ if (0 != ferror(file) )
+ {
+ BX_ERROR_SET(_err, BX_ERROR_READERWRITER_WRITE, "ProcessWriter: write error.");
+ }
+
+ return size >= 0 ? size : 0;
+ }
+
+ return size;
+ }
+
+ int32_t ProcessWriter::getExitCode() const
+ {
+ return m_exitCode;
+ }
+#endif // BX_CONFIG_CRT_PROCESS
+
+} // namespace bx
diff --git a/3rdparty/bx/src/debug.cpp b/3rdparty/bx/src/debug.cpp
new file mode 100644
index 00000000000..550eef6e5f6
--- /dev/null
+++ b/3rdparty/bx/src/debug.cpp
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2010-2017 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ */
+
+#include <bx/debug.h>
+#include <bx/string.h> // isPrint
+#include <inttypes.h> // PRIx*
+
+#if BX_PLATFORM_ANDROID
+# include <android/log.h>
+#elif BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT || BX_PLATFORM_XBOX360 || BX_PLATFORM_XBOXONE
+extern "C" __declspec(dllimport) void __stdcall OutputDebugStringA(const char* _str);
+#elif BX_PLATFORM_IOS || BX_PLATFORM_OSX
+# if defined(__OBJC__)
+# import <Foundation/NSObjCRuntime.h>
+# else
+# include <CoreFoundation/CFString.h>
+extern "C" void NSLog(CFStringRef _format, ...);
+# endif // defined(__OBJC__)
+#elif 0 // BX_PLATFORM_EMSCRIPTEN
+# include <emscripten.h>
+#else
+# include <stdio.h> // fputs, fflush
+#endif // BX_PLATFORM_WINDOWS
+
+namespace bx
+{
+ void debugBreak()
+ {
+#if BX_COMPILER_MSVC
+ __debugbreak();
+#elif BX_CPU_ARM
+ __builtin_trap();
+// asm("bkpt 0");
+#elif !BX_PLATFORM_NACL && BX_CPU_X86 && (BX_COMPILER_GCC || BX_COMPILER_CLANG)
+ // NaCl doesn't like int 3:
+ // NativeClient: NaCl module load failed: Validation failure. File violates Native Client safety rules.
+ __asm__ ("int $3");
+#else // cross platform implementation
+ int* int3 = (int*)3L;
+ *int3 = 3;
+#endif // BX
+ }
+
+ void debugOutput(const char* _out)
+ {
+#if BX_PLATFORM_ANDROID
+# ifndef BX_ANDROID_LOG_TAG
+# define BX_ANDROID_LOG_TAG ""
+# endif // BX_ANDROID_LOG_TAG
+ __android_log_write(ANDROID_LOG_DEBUG, BX_ANDROID_LOG_TAG, _out);
+#elif BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT || BX_PLATFORM_XBOX360 || BX_PLATFORM_XBOXONE
+ OutputDebugStringA(_out);
+#elif BX_PLATFORM_IOS || BX_PLATFORM_OSX
+# if defined(__OBJC__)
+ NSLog(@"%s", _out);
+# else
+ NSLog(__CFStringMakeConstantString("%s"), _out);
+# endif // defined(__OBJC__)
+#elif 0 // BX_PLATFORM_EMSCRIPTEN
+ emscripten_log(EM_LOG_CONSOLE, "%s", _out);
+#else
+ fputs(_out, stdout);
+ fflush(stdout);
+#endif // BX_PLATFORM_
+ }
+
+ void debugPrintfVargs(const char* _format, va_list _argList)
+ {
+ char temp[8192];
+ char* out = temp;
+ int32_t len = vsnprintf(out, sizeof(temp), _format, _argList);
+ if ( (int32_t)sizeof(temp) < len)
+ {
+ out = (char*)alloca(len+1);
+ len = vsnprintf(out, len, _format, _argList);
+ }
+ out[len] = '\0';
+ debugOutput(out);
+ }
+
+ void debugPrintf(const char* _format, ...)
+ {
+ va_list argList;
+ va_start(argList, _format);
+ debugPrintfVargs(_format, argList);
+ va_end(argList);
+ }
+
+#define DBG_ADDRESS "%" PRIxPTR
+
+ void debugPrintfData(const void* _data, uint32_t _size, const char* _format, ...)
+ {
+#define HEX_DUMP_WIDTH 16
+#define HEX_DUMP_SPACE_WIDTH 48
+#define HEX_DUMP_FORMAT "%-" BX_STRINGIZE(HEX_DUMP_SPACE_WIDTH) "." BX_STRINGIZE(HEX_DUMP_SPACE_WIDTH) "s"
+
+ va_list argList;
+ va_start(argList, _format);
+ debugPrintfVargs(_format, argList);
+ va_end(argList);
+
+ debugPrintf("\ndata: " DBG_ADDRESS ", size: %d\n", _data, _size);
+
+ if (NULL != _data)
+ {
+ const uint8_t* data = reinterpret_cast<const uint8_t*>(_data);
+ char hex[HEX_DUMP_WIDTH*3+1];
+ char ascii[HEX_DUMP_WIDTH+1];
+ uint32_t hexPos = 0;
+ uint32_t asciiPos = 0;
+ for (uint32_t ii = 0; ii < _size; ++ii)
+ {
+ snprintf(&hex[hexPos], sizeof(hex)-hexPos, "%02x ", data[asciiPos]);
+ hexPos += 3;
+
+ ascii[asciiPos] = isPrint(data[asciiPos]) ? data[asciiPos] : '.';
+ asciiPos++;
+
+ if (HEX_DUMP_WIDTH == asciiPos)
+ {
+ ascii[asciiPos] = '\0';
+ debugPrintf("\t" DBG_ADDRESS "\t" HEX_DUMP_FORMAT "\t%s\n", data, hex, ascii);
+ data += asciiPos;
+ hexPos = 0;
+ asciiPos = 0;
+ }
+ }
+
+ if (0 != asciiPos)
+ {
+ ascii[asciiPos] = '\0';
+ debugPrintf("\t" DBG_ADDRESS "\t" HEX_DUMP_FORMAT "\t%s\n", data, hex, ascii);
+ }
+ }
+
+#undef HEX_DUMP_WIDTH
+#undef HEX_DUMP_SPACE_WIDTH
+#undef HEX_DUMP_FORMAT
+ }
+
+} // namespace bx
diff --git a/3rdparty/bx/src/dtoa.cpp b/3rdparty/bx/src/dtoa.cpp
new file mode 100644
index 00000000000..05ac387fec2
--- /dev/null
+++ b/3rdparty/bx/src/dtoa.cpp
@@ -0,0 +1,528 @@
+/*
+ * Copyright 2010-2017 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ */
+
+#include <bx/cpu.h>
+#include <bx/fpumath.h>
+#include <bx/string.h>
+#include <bx/uint32_t.h>
+
+namespace bx
+{
+ // https://github.com/miloyip/dtoa-benchmark
+ //
+ // Copyright (C) 2014 Milo Yip
+ //
+ // Permission is hereby granted, free of charge, to any person obtaining a copy
+ // of this software and associated documentation files (the "Software"), to deal
+ // in the Software without restriction, including without limitation the rights
+ // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ // copies of the Software, and to permit persons to whom the Software is
+ // furnished to do so, subject to the following conditions:
+ //
+ // The above copyright notice and this permission notice shall be included in
+ // all copies or substantial portions of the Software.
+ //
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ // THE SOFTWARE.
+ //
+ struct DiyFp
+ {
+ DiyFp()
+ {
+ }
+
+ DiyFp(uint64_t _f, int32_t _e)
+ : f(_f)
+ , e(_e)
+ {
+ }
+
+ DiyFp(double d)
+ {
+ union
+ {
+ double d;
+ uint64_t u64;
+ } u = { d };
+
+ int32_t biased_e = (u.u64 & kDpExponentMask) >> kDpSignificandSize;
+ uint64_t significand = (u.u64 & kDpSignificandMask);
+ if (biased_e != 0)
+ {
+ f = significand + kDpHiddenBit;
+ e = biased_e - kDpExponentBias;
+ }
+ else
+ {
+ f = significand;
+ e = kDpMinExponent + 1;
+ }
+ }
+
+ DiyFp operator-(const DiyFp& rhs) const
+ {
+ BX_CHECK(e == rhs.e, "");
+ BX_CHECK(f >= rhs.f, "");
+ return DiyFp(f - rhs.f, e);
+ }
+
+ DiyFp operator*(const DiyFp& rhs) const
+ {
+ const uint64_t M32 = 0xFFFFFFFF;
+ const uint64_t a = f >> 32;
+ const uint64_t b = f & M32;
+ const uint64_t c = rhs.f >> 32;
+ const uint64_t d = rhs.f & M32;
+ const uint64_t ac = a * c;
+ const uint64_t bc = b * c;
+ const uint64_t ad = a * d;
+ const uint64_t bd = b * d;
+ uint64_t tmp = (bd >> 32) + (ad & M32) + (bc & M32);
+ tmp += 1U << 31; /// mult_round
+ return DiyFp(ac + (ad >> 32) + (bc >> 32) + (tmp >> 32), e + rhs.e + 64);
+ }
+
+ DiyFp Normalize() const
+ {
+ uint32_t s = uint64_cntlz(f);
+ return DiyFp(f << s, e - s);
+ }
+
+ DiyFp NormalizeBoundary() const
+ {
+ uint32_t index = uint64_cntlz(f);
+ return DiyFp (f << index, e - index);
+ }
+
+ void NormalizedBoundaries(DiyFp* minus, DiyFp* plus) const
+ {
+ DiyFp pl = DiyFp((f << 1) + 1, e - 1).NormalizeBoundary();
+ DiyFp mi = (f == kDpHiddenBit) ? DiyFp((f << 2) - 1, e - 2) : DiyFp((f << 1) - 1, e - 1);
+ mi.f <<= mi.e - pl.e;
+ mi.e = pl.e;
+ *plus = pl;
+ *minus = mi;
+ }
+
+#define UINT64_C2(h, l) ((static_cast<uint64_t>(h) << 32) | static_cast<uint64_t>(l))
+
+ static const int32_t kDiySignificandSize = 64;
+ static const int32_t kDpSignificandSize = 52;
+ static const int32_t kDpExponentBias = 0x3FF + kDpSignificandSize;
+ static const int32_t kDpMinExponent = -kDpExponentBias;
+ static const uint64_t kDpExponentMask = UINT64_C2(0x7FF00000, 0x00000000);
+ static const uint64_t kDpSignificandMask = UINT64_C2(0x000FFFFF, 0xFFFFFFFF);
+ static const uint64_t kDpHiddenBit = UINT64_C2(0x00100000, 0x00000000);
+
+ uint64_t f;
+ int32_t e;
+ };
+
+ // 10^-348, 10^-340, ..., 10^340
+ static const uint64_t s_kCachedPowers_F[] =
+ {
+ UINT64_C2(0xfa8fd5a0, 0x081c0288), UINT64_C2(0xbaaee17f, 0xa23ebf76),
+ UINT64_C2(0x8b16fb20, 0x3055ac76), UINT64_C2(0xcf42894a, 0x5dce35ea),
+ UINT64_C2(0x9a6bb0aa, 0x55653b2d), UINT64_C2(0xe61acf03, 0x3d1a45df),
+ UINT64_C2(0xab70fe17, 0xc79ac6ca), UINT64_C2(0xff77b1fc, 0xbebcdc4f),
+ UINT64_C2(0xbe5691ef, 0x416bd60c), UINT64_C2(0x8dd01fad, 0x907ffc3c),
+ UINT64_C2(0xd3515c28, 0x31559a83), UINT64_C2(0x9d71ac8f, 0xada6c9b5),
+ UINT64_C2(0xea9c2277, 0x23ee8bcb), UINT64_C2(0xaecc4991, 0x4078536d),
+ UINT64_C2(0x823c1279, 0x5db6ce57), UINT64_C2(0xc2109436, 0x4dfb5637),
+ UINT64_C2(0x9096ea6f, 0x3848984f), UINT64_C2(0xd77485cb, 0x25823ac7),
+ UINT64_C2(0xa086cfcd, 0x97bf97f4), UINT64_C2(0xef340a98, 0x172aace5),
+ UINT64_C2(0xb23867fb, 0x2a35b28e), UINT64_C2(0x84c8d4df, 0xd2c63f3b),
+ UINT64_C2(0xc5dd4427, 0x1ad3cdba), UINT64_C2(0x936b9fce, 0xbb25c996),
+ UINT64_C2(0xdbac6c24, 0x7d62a584), UINT64_C2(0xa3ab6658, 0x0d5fdaf6),
+ UINT64_C2(0xf3e2f893, 0xdec3f126), UINT64_C2(0xb5b5ada8, 0xaaff80b8),
+ UINT64_C2(0x87625f05, 0x6c7c4a8b), UINT64_C2(0xc9bcff60, 0x34c13053),
+ UINT64_C2(0x964e858c, 0x91ba2655), UINT64_C2(0xdff97724, 0x70297ebd),
+ UINT64_C2(0xa6dfbd9f, 0xb8e5b88f), UINT64_C2(0xf8a95fcf, 0x88747d94),
+ UINT64_C2(0xb9447093, 0x8fa89bcf), UINT64_C2(0x8a08f0f8, 0xbf0f156b),
+ UINT64_C2(0xcdb02555, 0x653131b6), UINT64_C2(0x993fe2c6, 0xd07b7fac),
+ UINT64_C2(0xe45c10c4, 0x2a2b3b06), UINT64_C2(0xaa242499, 0x697392d3),
+ UINT64_C2(0xfd87b5f2, 0x8300ca0e), UINT64_C2(0xbce50864, 0x92111aeb),
+ UINT64_C2(0x8cbccc09, 0x6f5088cc), UINT64_C2(0xd1b71758, 0xe219652c),
+ UINT64_C2(0x9c400000, 0x00000000), UINT64_C2(0xe8d4a510, 0x00000000),
+ UINT64_C2(0xad78ebc5, 0xac620000), UINT64_C2(0x813f3978, 0xf8940984),
+ UINT64_C2(0xc097ce7b, 0xc90715b3), UINT64_C2(0x8f7e32ce, 0x7bea5c70),
+ UINT64_C2(0xd5d238a4, 0xabe98068), UINT64_C2(0x9f4f2726, 0x179a2245),
+ UINT64_C2(0xed63a231, 0xd4c4fb27), UINT64_C2(0xb0de6538, 0x8cc8ada8),
+ UINT64_C2(0x83c7088e, 0x1aab65db), UINT64_C2(0xc45d1df9, 0x42711d9a),
+ UINT64_C2(0x924d692c, 0xa61be758), UINT64_C2(0xda01ee64, 0x1a708dea),
+ UINT64_C2(0xa26da399, 0x9aef774a), UINT64_C2(0xf209787b, 0xb47d6b85),
+ UINT64_C2(0xb454e4a1, 0x79dd1877), UINT64_C2(0x865b8692, 0x5b9bc5c2),
+ UINT64_C2(0xc83553c5, 0xc8965d3d), UINT64_C2(0x952ab45c, 0xfa97a0b3),
+ UINT64_C2(0xde469fbd, 0x99a05fe3), UINT64_C2(0xa59bc234, 0xdb398c25),
+ UINT64_C2(0xf6c69a72, 0xa3989f5c), UINT64_C2(0xb7dcbf53, 0x54e9bece),
+ UINT64_C2(0x88fcf317, 0xf22241e2), UINT64_C2(0xcc20ce9b, 0xd35c78a5),
+ UINT64_C2(0x98165af3, 0x7b2153df), UINT64_C2(0xe2a0b5dc, 0x971f303a),
+ UINT64_C2(0xa8d9d153, 0x5ce3b396), UINT64_C2(0xfb9b7cd9, 0xa4a7443c),
+ UINT64_C2(0xbb764c4c, 0xa7a44410), UINT64_C2(0x8bab8eef, 0xb6409c1a),
+ UINT64_C2(0xd01fef10, 0xa657842c), UINT64_C2(0x9b10a4e5, 0xe9913129),
+ UINT64_C2(0xe7109bfb, 0xa19c0c9d), UINT64_C2(0xac2820d9, 0x623bf429),
+ UINT64_C2(0x80444b5e, 0x7aa7cf85), UINT64_C2(0xbf21e440, 0x03acdd2d),
+ UINT64_C2(0x8e679c2f, 0x5e44ff8f), UINT64_C2(0xd433179d, 0x9c8cb841),
+ UINT64_C2(0x9e19db92, 0xb4e31ba9), UINT64_C2(0xeb96bf6e, 0xbadf77d9),
+ UINT64_C2(0xaf87023b, 0x9bf0ee6b)
+ };
+
+ static const int16_t s_kCachedPowers_E[] =
+ {
+ -1220, -1193, -1166, -1140, -1113, -1087, -1060, -1034, -1007, -980,
+ -954, -927, -901, -874, -847, -821, -794, -768, -741, -715,
+ -688, -661, -635, -608, -582, -555, -529, -502, -475, -449,
+ -422, -396, -369, -343, -316, -289, -263, -236, -210, -183,
+ -157, -130, -103, -77, -50, -24, 3, 30, 56, 83,
+ 109, 136, 162, 189, 216, 242, 269, 295, 322, 348,
+ 375, 402, 428, 455, 481, 508, 534, 561, 588, 614,
+ 641, 667, 694, 720, 747, 774, 800, 827, 853, 880,
+ 907, 933, 960, 986, 1013, 1039, 1066
+ };
+
+ static const char s_cDigitsLut[200] =
+ {
+ '0', '0', '0', '1', '0', '2', '0', '3', '0', '4', '0', '5', '0', '6', '0', '7', '0', '8', '0', '9',
+ '1', '0', '1', '1', '1', '2', '1', '3', '1', '4', '1', '5', '1', '6', '1', '7', '1', '8', '1', '9',
+ '2', '0', '2', '1', '2', '2', '2', '3', '2', '4', '2', '5', '2', '6', '2', '7', '2', '8', '2', '9',
+ '3', '0', '3', '1', '3', '2', '3', '3', '3', '4', '3', '5', '3', '6', '3', '7', '3', '8', '3', '9',
+ '4', '0', '4', '1', '4', '2', '4', '3', '4', '4', '4', '5', '4', '6', '4', '7', '4', '8', '4', '9',
+ '5', '0', '5', '1', '5', '2', '5', '3', '5', '4', '5', '5', '5', '6', '5', '7', '5', '8', '5', '9',
+ '6', '0', '6', '1', '6', '2', '6', '3', '6', '4', '6', '5', '6', '6', '6', '7', '6', '8', '6', '9',
+ '7', '0', '7', '1', '7', '2', '7', '3', '7', '4', '7', '5', '7', '6', '7', '7', '7', '8', '7', '9',
+ '8', '0', '8', '1', '8', '2', '8', '3', '8', '4', '8', '5', '8', '6', '8', '7', '8', '8', '8', '9',
+ '9', '0', '9', '1', '9', '2', '9', '3', '9', '4', '9', '5', '9', '6', '9', '7', '9', '8', '9', '9'
+ };
+
+ static const uint32_t s_kPow10[] =
+ {
+ 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000
+ };
+
+ DiyFp GetCachedPower(int32_t e, int32_t* K)
+ {
+ double dk = (-61 - e) * 0.30102999566398114 + 347; // dk must be positive, so can do ceiling in positive
+ int32_t k = static_cast<int32_t>(dk);
+ if (k != dk)
+ {
+ k++;
+ }
+
+ uint32_t index = static_cast<uint32_t>((k >> 3) + 1);
+ *K = -(-348 + static_cast<int32_t>(index << 3)); // decimal exponent no need lookup table
+
+ BX_CHECK(index < sizeof(s_kCachedPowers_F) / sizeof(s_kCachedPowers_F[0]));
+ return DiyFp(s_kCachedPowers_F[index], s_kCachedPowers_E[index]);
+ }
+
+ void GrisuRound(char* buffer, int32_t len, uint64_t delta, uint64_t rest, uint64_t ten_kappa, uint64_t wp_w)
+ {
+ while (rest < wp_w
+ && delta - rest >= ten_kappa
+ && (rest + ten_kappa < wp_w || wp_w - rest > rest + ten_kappa - wp_w))
+ {
+ buffer[len - 1]--;
+ rest += ten_kappa;
+ }
+ }
+
+ uint32_t CountDecimalDigit32(uint32_t n)
+ {
+ // Simple pure C++ implementation was faster than __builtin_clz version in this situation.
+ if (n < 10) return 1;
+ if (n < 100) return 2;
+ if (n < 1000) return 3;
+ if (n < 10000) return 4;
+ if (n < 100000) return 5;
+ if (n < 1000000) return 6;
+ if (n < 10000000) return 7;
+ if (n < 100000000) return 8;
+ if (n < 1000000000) return 9;
+ return 10;
+ }
+
+ void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buffer, int32_t* len, int32_t* K)
+ {
+ const DiyFp one(uint64_t(1) << -Mp.e, Mp.e);
+ const DiyFp wp_w = Mp - W;
+ uint32_t p1 = static_cast<uint32_t>(Mp.f >> -one.e);
+ uint64_t p2 = Mp.f & (one.f - 1);
+ int32_t kappa = static_cast<int32_t>(CountDecimalDigit32(p1));
+ *len = 0;
+
+ while (kappa > 0)
+ {
+ uint32_t d;
+ switch (kappa)
+ {
+ case 10: d = p1 / 1000000000; p1 %= 1000000000; break;
+ case 9: d = p1 / 100000000; p1 %= 100000000; break;
+ case 8: d = p1 / 10000000; p1 %= 10000000; break;
+ case 7: d = p1 / 1000000; p1 %= 1000000; break;
+ case 6: d = p1 / 100000; p1 %= 100000; break;
+ case 5: d = p1 / 10000; p1 %= 10000; break;
+ case 4: d = p1 / 1000; p1 %= 1000; break;
+ case 3: d = p1 / 100; p1 %= 100; break;
+ case 2: d = p1 / 10; p1 %= 10; break;
+ case 1: d = p1; p1 = 0; break;
+ default:
+ d = 0;
+ break;
+ }
+
+ if (d || *len)
+ {
+ buffer[(*len)++] = '0' + static_cast<char>(d);
+ }
+
+ kappa--;
+ uint64_t tmp = (static_cast<uint64_t>(p1) << -one.e) + p2;
+ if (tmp <= delta)
+ {
+ *K += kappa;
+ GrisuRound(buffer, *len, delta, tmp, static_cast<uint64_t>(s_kPow10[kappa]) << -one.e, wp_w.f);
+ return;
+ }
+ }
+
+ // kappa = 0
+ for (;;)
+ {
+ p2 *= 10;
+ delta *= 10;
+ char d = static_cast<char>(p2 >> -one.e);
+ if (d || *len)
+ {
+ buffer[(*len)++] = '0' + d;
+ }
+
+ p2 &= one.f - 1;
+ kappa--;
+ if (p2 < delta)
+ {
+ *K += kappa;
+ GrisuRound(buffer, *len, delta, p2, one.f, wp_w.f * s_kPow10[-kappa]);
+ return;
+ }
+ }
+ }
+
+ void Grisu2(double value, char* buffer, int32_t* length, int32_t* K)
+ {
+ const DiyFp v(value);
+ DiyFp w_m, w_p;
+ v.NormalizedBoundaries(&w_m, &w_p);
+
+ const DiyFp c_mk = GetCachedPower(w_p.e, K);
+ const DiyFp W = v.Normalize() * c_mk;
+ DiyFp Wp = w_p * c_mk;
+ DiyFp Wm = w_m * c_mk;
+ Wm.f++;
+ Wp.f--;
+ DigitGen(W, Wp, Wp.f - Wm.f, buffer, length, K);
+ }
+
+ int32_t WriteExponent(int32_t K, char* buffer)
+ {
+ const char* ptr = buffer;
+
+ if (K < 0)
+ {
+ *buffer++ = '-';
+ K = -K;
+ }
+
+ if (K >= 100)
+ {
+ *buffer++ = '0' + static_cast<char>(K / 100);
+ K %= 100;
+ const char* d = s_cDigitsLut + K * 2;
+ *buffer++ = d[0];
+ *buffer++ = d[1];
+ }
+ else if (K >= 10)
+ {
+ const char* d = s_cDigitsLut + K * 2;
+ *buffer++ = d[0];
+ *buffer++ = d[1];
+ }
+ else
+ {
+ *buffer++ = '0' + static_cast<char>(K);
+ }
+
+ *buffer = '\0';
+
+ return int32_t(buffer - ptr);
+ }
+
+ int32_t Prettify(char* buffer, int32_t length, int32_t k)
+ {
+ const int32_t kk = length + k; // 10^(kk-1) <= v < 10^kk
+
+ if (length <= kk && kk <= 21)
+ {
+ // 1234e7 -> 12340000000
+ for (int32_t i = length; i < kk; i++)
+ {
+ buffer[i] = '0';
+ }
+
+ buffer[kk] = '.';
+ buffer[kk + 1] = '0';
+ buffer[kk + 2] = '\0';
+ return kk + 2;
+ }
+
+ if (0 < kk && kk <= 21)
+ {
+ // 1234e-2 -> 12.34
+ memmove(&buffer[kk + 1], &buffer[kk], length - kk);
+ buffer[kk] = '.';
+ buffer[length + 1] = '\0';
+ return length + 1;
+ }
+
+ if (-6 < kk && kk <= 0)
+ {
+ // 1234e-6 -> 0.001234
+ const int32_t offset = 2 - kk;
+ memmove(&buffer[offset], &buffer[0], length);
+ buffer[0] = '0';
+ buffer[1] = '.';
+ for (int32_t i = 2; i < offset; i++)
+ {
+ buffer[i] = '0';
+ }
+
+ buffer[length + offset] = '\0';
+ return length + offset;
+ }
+
+ if (length == 1)
+ {
+ // 1e30
+ buffer[1] = 'e';
+ int32_t exp = WriteExponent(kk - 1, &buffer[2]);
+ return 2 + exp;
+ }
+
+ // 1234e30 -> 1.234e33
+ memmove(&buffer[2], &buffer[1], length - 1);
+ buffer[1] = '.';
+ buffer[length + 1] = 'e';
+ int32_t exp = WriteExponent(kk - 1, &buffer[length + 2]);
+ return length + 2 + exp;
+ }
+
+ int32_t toString(char* _dst, size_t _max, double value)
+ {
+ if (isNan(value) )
+ {
+ return (int32_t)strlncpy(_dst, _max, "NaN");
+ }
+ else if (isInfinite(value) )
+ {
+ return (int32_t)strlncpy(_dst, _max, "Inf");
+ }
+
+ int32_t sign = 0.0 > value ? 1 : 0;
+ if (1 == sign)
+ {
+ *_dst++ = '-';
+ --_max;
+ value = -value;
+ }
+
+ int32_t len;
+ if (0.0 == value)
+ {
+ len = (int32_t)strlncpy(_dst, _max, "0.0");
+ }
+ else
+ {
+ int32_t kk;
+ Grisu2(value, _dst, &len, &kk);
+ len = Prettify(_dst, len, kk);
+ }
+
+ return len + sign;
+ }
+
+ static void reverse(char* _dst, size_t _len)
+ {
+ for (size_t ii = 0, jj = _len - 1; ii < jj; ++ii, --jj)
+ {
+ xchg(_dst[ii], _dst[jj]);
+ }
+ }
+
+ int32_t toString(char* _dst, size_t _max, int32_t _value, uint32_t _base)
+ {
+ if (_base == 10
+ && _value < 0)
+ {
+ if (_max < 1)
+ {
+ return 0;
+ }
+
+ _max = toString(_dst + 1, _max - 1, uint32_t(-_value), _base);
+ if (_max == 0)
+ {
+ return 0;
+ }
+
+ *_dst = '-';
+ return int32_t(_max + 1);
+ }
+
+ return toString(_dst, _max, uint32_t(_value), _base);
+ }
+
+ int32_t toString(char* _dst, size_t _max, uint32_t _value, uint32_t _base)
+ {
+ char data[32];
+ size_t len = 0;
+
+ if (_base > 16
+ || _base < 2)
+ {
+ return 0;
+ }
+
+ do
+ {
+ const uint32_t rem = _value % _base;
+ _value /= _base;
+ if (rem < 10)
+ {
+ data[len++] = char('0' + rem);
+ }
+ else
+ {
+ data[len++] = char('a' + rem - 10);
+ }
+
+ } while (_value != 0);
+
+ if (_max < len + 1)
+ {
+ return 0;
+ }
+
+ reverse(data, len);
+
+ memcpy(_dst, data, len);
+ _dst[len] = '\0';
+ return int32_t(len);
+ }
+
+} // namespace bx
diff --git a/3rdparty/bx/src/fpumath.cpp b/3rdparty/bx/src/fpumath.cpp
new file mode 100644
index 00000000000..da463e08767
--- /dev/null
+++ b/3rdparty/bx/src/fpumath.cpp
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2011-2017 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ */
+
+#include <bx/fpumath.h>
+
+namespace bx
+{
+ const float pi = 3.14159265358979323846f;
+ const float invPi = 1.0f/3.14159265358979323846f;
+ const float piHalf = 1.57079632679489661923f;
+ const float sqrt2 = 1.41421356237309504880f;
+#if BX_COMPILER_MSVC
+ const float huge = float(HUGE_VAL);
+#else
+ const float huge = HUGE_VALF;
+#endif // BX_COMPILER_MSVC
+
+ void mtx3Inverse(float* __restrict _result, const float* __restrict _a)
+ {
+ float xx = _a[0];
+ float xy = _a[1];
+ float xz = _a[2];
+ float yx = _a[3];
+ float yy = _a[4];
+ float yz = _a[5];
+ float zx = _a[6];
+ float zy = _a[7];
+ float zz = _a[8];
+
+ float det = 0.0f;
+ det += xx * (yy*zz - yz*zy);
+ det -= xy * (yx*zz - yz*zx);
+ det += xz * (yx*zy - yy*zx);
+
+ float invDet = 1.0f/det;
+
+ _result[0] = +(yy*zz - yz*zy) * invDet;
+ _result[1] = -(xy*zz - xz*zy) * invDet;
+ _result[2] = +(xy*yz - xz*yy) * invDet;
+
+ _result[3] = -(yx*zz - yz*zx) * invDet;
+ _result[4] = +(xx*zz - xz*zx) * invDet;
+ _result[5] = -(xx*yz - xz*yx) * invDet;
+
+ _result[6] = +(yx*zy - yy*zx) * invDet;
+ _result[7] = -(xx*zy - xy*zx) * invDet;
+ _result[8] = +(xx*yy - xy*yx) * invDet;
+ }
+
+ void mtxInverse(float* __restrict _result, const float* __restrict _a)
+ {
+ float xx = _a[ 0];
+ float xy = _a[ 1];
+ float xz = _a[ 2];
+ float xw = _a[ 3];
+ float yx = _a[ 4];
+ float yy = _a[ 5];
+ float yz = _a[ 6];
+ float yw = _a[ 7];
+ float zx = _a[ 8];
+ float zy = _a[ 9];
+ float zz = _a[10];
+ float zw = _a[11];
+ float wx = _a[12];
+ float wy = _a[13];
+ float wz = _a[14];
+ float ww = _a[15];
+
+ float det = 0.0f;
+ det += xx * (yy*(zz*ww - zw*wz) - yz*(zy*ww - zw*wy) + yw*(zy*wz - zz*wy) );
+ det -= xy * (yx*(zz*ww - zw*wz) - yz*(zx*ww - zw*wx) + yw*(zx*wz - zz*wx) );
+ det += xz * (yx*(zy*ww - zw*wy) - yy*(zx*ww - zw*wx) + yw*(zx*wy - zy*wx) );
+ det -= xw * (yx*(zy*wz - zz*wy) - yy*(zx*wz - zz*wx) + yz*(zx*wy - zy*wx) );
+
+ float invDet = 1.0f/det;
+
+ _result[ 0] = +(yy*(zz*ww - wz*zw) - yz*(zy*ww - wy*zw) + yw*(zy*wz - wy*zz) ) * invDet;
+ _result[ 1] = -(xy*(zz*ww - wz*zw) - xz*(zy*ww - wy*zw) + xw*(zy*wz - wy*zz) ) * invDet;
+ _result[ 2] = +(xy*(yz*ww - wz*yw) - xz*(yy*ww - wy*yw) + xw*(yy*wz - wy*yz) ) * invDet;
+ _result[ 3] = -(xy*(yz*zw - zz*yw) - xz*(yy*zw - zy*yw) + xw*(yy*zz - zy*yz) ) * invDet;
+
+ _result[ 4] = -(yx*(zz*ww - wz*zw) - yz*(zx*ww - wx*zw) + yw*(zx*wz - wx*zz) ) * invDet;
+ _result[ 5] = +(xx*(zz*ww - wz*zw) - xz*(zx*ww - wx*zw) + xw*(zx*wz - wx*zz) ) * invDet;
+ _result[ 6] = -(xx*(yz*ww - wz*yw) - xz*(yx*ww - wx*yw) + xw*(yx*wz - wx*yz) ) * invDet;
+ _result[ 7] = +(xx*(yz*zw - zz*yw) - xz*(yx*zw - zx*yw) + xw*(yx*zz - zx*yz) ) * invDet;
+
+ _result[ 8] = +(yx*(zy*ww - wy*zw) - yy*(zx*ww - wx*zw) + yw*(zx*wy - wx*zy) ) * invDet;
+ _result[ 9] = -(xx*(zy*ww - wy*zw) - xy*(zx*ww - wx*zw) + xw*(zx*wy - wx*zy) ) * invDet;
+ _result[10] = +(xx*(yy*ww - wy*yw) - xy*(yx*ww - wx*yw) + xw*(yx*wy - wx*yy) ) * invDet;
+ _result[11] = -(xx*(yy*zw - zy*yw) - xy*(yx*zw - zx*yw) + xw*(yx*zy - zx*yy) ) * invDet;
+
+ _result[12] = -(yx*(zy*wz - wy*zz) - yy*(zx*wz - wx*zz) + yz*(zx*wy - wx*zy) ) * invDet;
+ _result[13] = +(xx*(zy*wz - wy*zz) - xy*(zx*wz - wx*zz) + xz*(zx*wy - wx*zy) ) * invDet;
+ _result[14] = -(xx*(yy*wz - wy*yz) - xy*(yx*wz - wx*yz) + xz*(yx*wy - wx*yy) ) * invDet;
+ _result[15] = +(xx*(yy*zz - zy*yz) - xy*(yx*zz - zx*yz) + xz*(yx*zy - zx*yy) ) * invDet;
+ }
+
+} // namespace bx
diff --git a/3rdparty/bx/src/mutex.cpp b/3rdparty/bx/src/mutex.cpp
new file mode 100644
index 00000000000..00e517684e2
--- /dev/null
+++ b/3rdparty/bx/src/mutex.cpp
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2010-2017 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ */
+
+#include <bx/mutex.h>
+
+#if BX_CONFIG_SUPPORTS_THREADING
+
+#if 0 \
+ || BX_PLATFORM_ANDROID \
+ || BX_PLATFORM_LINUX \
+ || BX_PLATFORM_NACL \
+ || BX_PLATFORM_IOS \
+ || BX_PLATFORM_OSX
+# include <pthread.h>
+#elif 0 \
+ || BX_PLATFORM_WINDOWS \
+ || BX_PLATFORM_WINRT \
+ || BX_PLATFORM_XBOX360
+# include <errno.h>
+#endif // BX_PLATFORM_
+
+namespace bx
+{
+#if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 || BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT
+ typedef CRITICAL_SECTION pthread_mutex_t;
+ typedef unsigned pthread_mutexattr_t;
+
+ inline int pthread_mutex_lock(pthread_mutex_t* _mutex)
+ {
+ EnterCriticalSection(_mutex);
+ return 0;
+ }
+
+ inline int pthread_mutex_unlock(pthread_mutex_t* _mutex)
+ {
+ LeaveCriticalSection(_mutex);
+ return 0;
+ }
+
+ inline int pthread_mutex_trylock(pthread_mutex_t* _mutex)
+ {
+ return TryEnterCriticalSection(_mutex) ? 0 : EBUSY;
+ }
+
+ inline int pthread_mutex_init(pthread_mutex_t* _mutex, pthread_mutexattr_t* /*_attr*/)
+ {
+#if BX_PLATFORM_WINRT
+ InitializeCriticalSectionEx(_mutex, 4000, 0); // docs recommend 4000 spincount as sane default
+#else
+ InitializeCriticalSection(_mutex);
+#endif
+ return 0;
+ }
+
+ inline int pthread_mutex_destroy(pthread_mutex_t* _mutex)
+ {
+ DeleteCriticalSection(_mutex);
+ return 0;
+ }
+#endif // BX_PLATFORM_
+
+ Mutex::Mutex()
+ {
+ pthread_mutexattr_t attr;
+#if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 || BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT
+#else
+ pthread_mutexattr_init(&attr);
+ pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+#endif // BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 || BX_PLATFORM_WINRT
+ pthread_mutex_init(&m_handle, &attr);
+ }
+
+ Mutex::~Mutex()
+ {
+ pthread_mutex_destroy(&m_handle);
+ }
+
+ void Mutex::lock()
+ {
+ pthread_mutex_lock(&m_handle);
+ }
+
+ void Mutex::unlock()
+ {
+ pthread_mutex_unlock(&m_handle);
+ }
+
+} // namespace bx
+
+#endif // BX_MUTEX_H_HEADER_GUARD
diff --git a/3rdparty/bx/src/os.cpp b/3rdparty/bx/src/os.cpp
new file mode 100644
index 00000000000..5f1d45945b7
--- /dev/null
+++ b/3rdparty/bx/src/os.cpp
@@ -0,0 +1,454 @@
+/*
+ * Copyright 2010-2017 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ */
+
+#include <bx/os.h>
+#include <bx/uint32_t.h>
+#include <bx/string.h>
+
+#include <stdio.h>
+
+#if BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT
+# include <windows.h>
+# include <psapi.h>
+#elif BX_PLATFORM_ANDROID \
+ || BX_PLATFORM_EMSCRIPTEN \
+ || BX_PLATFORM_BSD \
+ || BX_PLATFORM_HURD \
+ || BX_PLATFORM_IOS \
+ || BX_PLATFORM_LINUX \
+ || BX_PLATFORM_NACL \
+ || BX_PLATFORM_OSX \
+ || BX_PLATFORM_PS4 \
+ || BX_PLATFORM_RPI \
+ || BX_PLATFORM_STEAMLINK
+# include <sched.h> // sched_yield
+# if BX_PLATFORM_BSD \
+ || BX_PLATFORM_IOS \
+ || BX_PLATFORM_NACL \
+ || BX_PLATFORM_OSX \
+ || BX_PLATFORM_PS4 \
+ || BX_PLATFORM_STEAMLINK
+# include <pthread.h> // mach_port_t
+# endif // BX_PLATFORM_*
+
+# include <time.h> // nanosleep
+# if !BX_PLATFORM_PS4 && !BX_PLATFORM_NACL
+# include <dlfcn.h> // dlopen, dlclose, dlsym
+# endif // !BX_PLATFORM_PS4 && !BX_PLATFORM_NACL
+
+# if BX_PLATFORM_ANDROID
+# include <malloc.h> // mallinfo
+# elif BX_PLATFORM_LINUX \
+ || BX_PLATFORM_RPI \
+ || BX_PLATFORM_STEAMLINK
+# include <unistd.h> // syscall
+# include <sys/syscall.h>
+# elif BX_PLATFORM_OSX
+# include <mach/mach.h> // mach_task_basic_info
+# elif BX_PLATFORM_HURD
+# include <pthread/pthread.h> // pthread_self
+# elif BX_PLATFORM_ANDROID
+# include "debug.h" // getTid is not implemented...
+# endif // BX_PLATFORM_ANDROID
+#endif // BX_PLATFORM_
+
+#if BX_CRT_MSVC
+# include <direct.h> // _getcwd
+#else
+# include <unistd.h> // getcwd
+#endif // BX_CRT_MSVC
+
+namespace bx
+{
+
+ void sleep(uint32_t _ms)
+ {
+#if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360
+ ::Sleep(_ms);
+#elif BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT
+ BX_UNUSED(_ms);
+ debugOutput("sleep is not implemented"); debugBreak();
+#else
+ timespec req = {(time_t)_ms/1000, (long)((_ms%1000)*1000000)};
+ timespec rem = {0, 0};
+ ::nanosleep(&req, &rem);
+#endif // BX_PLATFORM_
+ }
+
+ void yield()
+ {
+#if BX_PLATFORM_WINDOWS
+ ::SwitchToThread();
+#elif BX_PLATFORM_XBOX360
+ ::Sleep(0);
+#elif BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT
+ debugOutput("yield is not implemented"); debugBreak();
+#else
+ ::sched_yield();
+#endif // BX_PLATFORM_
+ }
+
+ uint32_t getTid()
+ {
+#if BX_PLATFORM_WINDOWS
+ return ::GetCurrentThreadId();
+#elif BX_PLATFORM_LINUX || BX_PLATFORM_RPI || BX_PLATFORM_STEAMLINK
+ return (pid_t)::syscall(SYS_gettid);
+#elif BX_PLATFORM_IOS || BX_PLATFORM_OSX
+ return (mach_port_t)::pthread_mach_thread_np(pthread_self() );
+#elif BX_PLATFORM_BSD || BX_PLATFORM_NACL
+ // Casting __nc_basic_thread_data*... need better way to do this.
+ return *(uint32_t*)::pthread_self();
+#elif BX_PLATFORM_HURD
+ return (pthread_t)::pthread_self();
+#else
+//# pragma message "not implemented."
+ debugOutput("getTid is not implemented"); debugBreak();
+ return 0;
+#endif //
+ }
+
+ size_t getProcessMemoryUsed()
+ {
+#if BX_PLATFORM_ANDROID
+ struct mallinfo mi = mallinfo();
+ return mi.uordblks;
+#elif BX_PLATFORM_LINUX || BX_PLATFORM_HURD
+ FILE* file = fopen("/proc/self/statm", "r");
+ if (NULL == file)
+ {
+ return 0;
+ }
+
+ long pages = 0;
+ int items = fscanf(file, "%*s%ld", &pages);
+ fclose(file);
+ return 1 == items
+ ? pages * sysconf(_SC_PAGESIZE)
+ : 0
+ ;
+#elif BX_PLATFORM_OSX
+# if defined(MACH_TASK_BASIC_INFO)
+ mach_task_basic_info info;
+ mach_msg_type_number_t infoCount = MACH_TASK_BASIC_INFO_COUNT;
+
+ int const result = task_info(mach_task_self()
+ , MACH_TASK_BASIC_INFO
+ , (task_info_t)&info
+ , &infoCount
+ );
+# else // MACH_TASK_BASIC_INFO
+ task_basic_info info;
+ mach_msg_type_number_t infoCount = TASK_BASIC_INFO_COUNT;
+
+ int const result = task_info(mach_task_self()
+ , TASK_BASIC_INFO
+ , (task_info_t)&info
+ , &infoCount
+ );
+# endif // MACH_TASK_BASIC_INFO
+ if (KERN_SUCCESS != result)
+ {
+ return 0;
+ }
+
+ return info.resident_size;
+#elif BX_PLATFORM_WINDOWS
+ PROCESS_MEMORY_COUNTERS pmc;
+ GetProcessMemoryInfo(GetCurrentProcess()
+ , &pmc
+ , sizeof(pmc)
+ );
+ return pmc.WorkingSetSize;
+#else
+ return 0;
+#endif // BX_PLATFORM_*
+ }
+
+ void* dlopen(const char* _filePath)
+ {
+#if BX_PLATFORM_WINDOWS
+ return (void*)::LoadLibraryA(_filePath);
+#elif BX_PLATFORM_EMSCRIPTEN \
+ || BX_PLATFORM_NACL \
+ || BX_PLATFORM_PS4 \
+ || BX_PLATFORM_XBOXONE \
+ || BX_PLATFORM_WINRT
+ BX_UNUSED(_filePath);
+ return NULL;
+#else
+ return ::dlopen(_filePath, RTLD_LOCAL|RTLD_LAZY);
+#endif // BX_PLATFORM_
+ }
+
+ void dlclose(void* _handle)
+ {
+#if BX_PLATFORM_WINDOWS
+ ::FreeLibrary( (HMODULE)_handle);
+#elif BX_PLATFORM_EMSCRIPTEN \
+ || BX_PLATFORM_NACL \
+ || BX_PLATFORM_PS4 \
+ || BX_PLATFORM_XBOXONE \
+ || BX_PLATFORM_WINRT
+ BX_UNUSED(_handle);
+#else
+ ::dlclose(_handle);
+#endif // BX_PLATFORM_
+ }
+
+ void* dlsym(void* _handle, const char* _symbol)
+ {
+#if BX_PLATFORM_WINDOWS
+ return (void*)::GetProcAddress( (HMODULE)_handle, _symbol);
+#elif BX_PLATFORM_EMSCRIPTEN \
+ || BX_PLATFORM_NACL \
+ || BX_PLATFORM_PS4 \
+ || BX_PLATFORM_XBOXONE \
+ || BX_PLATFORM_WINRT
+ BX_UNUSED(_handle, _symbol);
+ return NULL;
+#else
+ return ::dlsym(_handle, _symbol);
+#endif // BX_PLATFORM_
+ }
+
+ bool getenv(const char* _name, char* _out, uint32_t* _inOutSize)
+ {
+#if BX_PLATFORM_WINDOWS
+ DWORD len = ::GetEnvironmentVariableA(_name, _out, *_inOutSize);
+ bool result = len != 0 && len < *_inOutSize;
+ *_inOutSize = len;
+ return result;
+#elif BX_PLATFORM_PS4 \
+ || BX_PLATFORM_XBOXONE \
+ || BX_PLATFORM_WINRT
+ BX_UNUSED(_name, _out, _inOutSize);
+ return false;
+#else
+ const char* ptr = ::getenv(_name);
+ uint32_t len = 0;
+ bool result = false;
+ if (NULL != ptr)
+ {
+ len = (uint32_t)strnlen(ptr);
+
+ result = len != 0 && len < *_inOutSize;
+ if (len < *_inOutSize)
+ {
+ strcpy(_out, ptr);
+ }
+ }
+
+ *_inOutSize = len;
+ return result;
+#endif // BX_PLATFORM_
+ }
+
+ void setenv(const char* _name, const char* _value)
+ {
+#if BX_PLATFORM_WINDOWS
+ ::SetEnvironmentVariableA(_name, _value);
+#elif BX_PLATFORM_PS4 \
+ || BX_PLATFORM_XBOXONE \
+ || BX_PLATFORM_WINRT
+ BX_UNUSED(_name, _value);
+#else
+ ::setenv(_name, _value, 1);
+#endif // BX_PLATFORM_
+ }
+
+ void unsetenv(const char* _name)
+ {
+#if BX_PLATFORM_WINDOWS
+ ::SetEnvironmentVariableA(_name, NULL);
+#elif BX_PLATFORM_PS4 \
+ || BX_PLATFORM_XBOXONE \
+ || BX_PLATFORM_WINRT
+ BX_UNUSED(_name);
+#else
+ ::unsetenv(_name);
+#endif // BX_PLATFORM_
+ }
+
+ int chdir(const char* _path)
+ {
+#if BX_PLATFORM_PS4 \
+ || BX_PLATFORM_XBOXONE \
+ || BX_PLATFORM_WINRT
+ BX_UNUSED(_path);
+ return -1;
+#elif BX_CRT_MSVC
+ return ::_chdir(_path);
+#else
+ return ::chdir(_path);
+#endif // BX_COMPILER_
+ }
+
+ char* pwd(char* _buffer, uint32_t _size)
+ {
+#if BX_PLATFORM_PS4 \
+ || BX_PLATFORM_XBOXONE \
+ || BX_PLATFORM_WINRT
+ BX_UNUSED(_buffer, _size);
+ return NULL;
+#elif BX_CRT_MSVC
+ return ::_getcwd(_buffer, (int)_size);
+#else
+ return ::getcwd(_buffer, _size);
+#endif // BX_COMPILER_
+ }
+
+ bool getTempPath(char* _out, uint32_t* _inOutSize)
+ {
+#if BX_PLATFORM_WINDOWS
+ uint32_t len = ::GetTempPathA(*_inOutSize, _out);
+ bool result = len != 0 && len < *_inOutSize;
+ *_inOutSize = len;
+ return result;
+#else
+ static const char* s_tmp[] =
+ {
+ "TMPDIR",
+ "TMP",
+ "TEMP",
+ "TEMPDIR",
+
+ NULL
+ };
+
+ for (const char** tmp = s_tmp; *tmp != NULL; ++tmp)
+ {
+ uint32_t len = *_inOutSize;
+ *_out = '\0';
+ bool result = getenv(*tmp, _out, &len);
+
+ if (result
+ && len != 0
+ && len < *_inOutSize)
+ {
+ *_inOutSize = len;
+ return result;
+ }
+ }
+
+ FileInfo fi;
+ if (stat("/tmp", fi)
+ && FileInfo::Directory == fi.m_type)
+ {
+ strlncpy(_out, *_inOutSize, "/tmp");
+ *_inOutSize = 4;
+ return true;
+ }
+
+ return false;
+#endif // BX_PLATFORM_*
+ }
+
+ bool stat(const char* _filePath, FileInfo& _fileInfo)
+ {
+ _fileInfo.m_size = 0;
+ _fileInfo.m_type = FileInfo::Count;
+
+#if BX_COMPILER_MSVC
+ struct ::_stat64 st;
+ int32_t result = ::_stat64(_filePath, &st);
+
+ if (0 != result)
+ {
+ return false;
+ }
+
+ if (0 != (st.st_mode & _S_IFREG) )
+ {
+ _fileInfo.m_type = FileInfo::Regular;
+ }
+ else if (0 != (st.st_mode & _S_IFDIR) )
+ {
+ _fileInfo.m_type = FileInfo::Directory;
+ }
+#else
+ struct ::stat st;
+ int32_t result = ::stat(_filePath, &st);
+ if (0 != result)
+ {
+ return false;
+ }
+
+ if (0 != (st.st_mode & S_IFREG) )
+ {
+ _fileInfo.m_type = FileInfo::Regular;
+ }
+ else if (0 != (st.st_mode & S_IFDIR) )
+ {
+ _fileInfo.m_type = FileInfo::Directory;
+ }
+#endif // BX_COMPILER_MSVC
+
+ _fileInfo.m_size = st.st_size;
+
+ return true;
+ }
+
+ void* exec(const char* const* _argv)
+ {
+#if BX_PLATFORM_LINUX || BX_PLATFORM_HURD
+ pid_t pid = fork();
+
+ if (0 == pid)
+ {
+ int result = execvp(_argv[0], const_cast<char *const*>(&_argv[1]) );
+ BX_UNUSED(result);
+ return NULL;
+ }
+
+ return (void*)uintptr_t(pid);
+#elif BX_PLATFORM_WINDOWS
+ STARTUPINFO si;
+ memset(&si, 0, sizeof(STARTUPINFO) );
+ si.cb = sizeof(STARTUPINFO);
+
+ PROCESS_INFORMATION pi;
+ memset(&pi, 0, sizeof(PROCESS_INFORMATION) );
+
+ int32_t total = 0;
+ for (uint32_t ii = 0; NULL != _argv[ii]; ++ii)
+ {
+ total += (int32_t)strnlen(_argv[ii]) + 1;
+ }
+
+ char* temp = (char*)alloca(total);
+ int32_t len = 0;
+ for(uint32_t ii = 0; NULL != _argv[ii]; ++ii)
+ {
+ len += snprintf(&temp[len], bx::uint32_imax(0, total-len)
+ , "%s "
+ , _argv[ii]
+ );
+ }
+
+ bool ok = !!CreateProcessA(_argv[0]
+ , temp
+ , NULL
+ , NULL
+ , false
+ , 0
+ , NULL
+ , NULL
+ , &si
+ , &pi
+ );
+ if (ok)
+ {
+ return pi.hProcess;
+ }
+
+ return NULL;
+#else
+ BX_UNUSED(_argv);
+ return NULL;
+#endif // BX_PLATFORM_LINUX || BX_PLATFORM_HURD
+ }
+
+} // namespace bx
diff --git a/3rdparty/bx/src/sem.cpp b/3rdparty/bx/src/sem.cpp
new file mode 100644
index 00000000000..2d3ca1574f8
--- /dev/null
+++ b/3rdparty/bx/src/sem.cpp
@@ -0,0 +1,221 @@
+/*
+ * Copyright 2010-2017 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ */
+
+#include <bx/sem.h>
+
+#if BX_CONFIG_SUPPORTS_THREADING
+
+#if BX_PLATFORM_POSIX
+# include <errno.h>
+# include <semaphore.h>
+# include <time.h>
+# include <pthread.h>
+#elif BX_PLATFORM_XBOXONE
+# include <synchapi.h>
+#elif BX_PLATFORM_XBOX360 || BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT
+# include <windows.h>
+# include <limits.h>
+#endif // BX_PLATFORM_
+
+namespace bx
+{
+#if BX_PLATFORM_POSIX
+
+# if BX_CONFIG_SEMAPHORE_PTHREAD
+ Semaphore::Semaphore()
+ : m_count(0)
+ {
+ int result;
+ result = pthread_mutex_init(&m_mutex, NULL);
+ BX_CHECK(0 == result, "pthread_mutex_init %d", result);
+
+ result = pthread_cond_init(&m_cond, NULL);
+ BX_CHECK(0 == result, "pthread_cond_init %d", result);
+
+ BX_UNUSED(result);
+ }
+
+ Semaphore::~Semaphore()
+ {
+ int result;
+ result = pthread_cond_destroy(&m_cond);
+ BX_CHECK(0 == result, "pthread_cond_destroy %d", result);
+
+ result = pthread_mutex_destroy(&m_mutex);
+ BX_CHECK(0 == result, "pthread_mutex_destroy %d", result);
+
+ BX_UNUSED(result);
+ }
+
+ void Semaphore::post(uint32_t _count)
+ {
+ int result = pthread_mutex_lock(&m_mutex);
+ BX_CHECK(0 == result, "pthread_mutex_lock %d", result);
+
+ for (uint32_t ii = 0; ii < _count; ++ii)
+ {
+ result = pthread_cond_signal(&m_cond);
+ BX_CHECK(0 == result, "pthread_cond_signal %d", result);
+ }
+
+ m_count += _count;
+
+ result = pthread_mutex_unlock(&m_mutex);
+ BX_CHECK(0 == result, "pthread_mutex_unlock %d", result);
+
+ BX_UNUSED(result);
+ }
+
+ bool Semaphore::wait(int32_t _msecs)
+ {
+ int result = pthread_mutex_lock(&m_mutex);
+ BX_CHECK(0 == result, "pthread_mutex_lock %d", result);
+
+# if BX_PLATFORM_NACL || BX_PLATFORM_OSX
+ BX_UNUSED(_msecs);
+ BX_CHECK(-1 == _msecs, "NaCl and OSX don't support pthread_cond_timedwait at this moment.");
+ while (0 == result
+ && 0 >= m_count)
+ {
+ result = pthread_cond_wait(&m_cond, &m_mutex);
+ }
+# elif BX_PLATFORM_IOS
+ if (-1 == _msecs)
+ {
+ while (0 == result
+ && 0 >= m_count)
+ {
+ result = pthread_cond_wait(&m_cond, &m_mutex);
+ }
+ }
+ else
+ {
+ timespec ts;
+ ts.tv_sec = _msecs/1000;
+ ts.tv_nsec = (_msecs%1000)*1000;
+
+ while (0 == result
+ && 0 >= m_count)
+ {
+ result = pthread_cond_timedwait_relative_np(&m_cond, &m_mutex, &ts);
+ }
+ }
+# else
+ timespec ts;
+ clock_gettime(CLOCK_REALTIME, &ts);
+ ts.tv_sec += _msecs/1000;
+ ts.tv_nsec += (_msecs%1000)*1000;
+
+ while (0 == result
+ && 0 >= m_count)
+ {
+ result = pthread_cond_timedwait(&m_cond, &m_mutex, &ts);
+ }
+# endif // BX_PLATFORM_NACL || BX_PLATFORM_OSX
+ bool ok = 0 == result;
+
+ if (ok)
+ {
+ --m_count;
+ }
+
+ result = pthread_mutex_unlock(&m_mutex);
+ BX_CHECK(0 == result, "pthread_mutex_unlock %d", result);
+
+ BX_UNUSED(result);
+
+ return ok;
+ }
+
+# else
+
+ Semaphore::Semaphore()
+ {
+ int32_t result = sem_init(&m_handle, 0, 0);
+ BX_CHECK(0 == result, "sem_init failed. errno %d", errno);
+ BX_UNUSED(result);
+ }
+
+ Semaphore::~Semaphore()
+ {
+ int32_t result = sem_destroy(&m_handle);
+ BX_CHECK(0 == result, "sem_destroy failed. errno %d", errno);
+ BX_UNUSED(result);
+ }
+
+ void Semaphore::post(uint32_t _count)
+ {
+ int32_t result;
+ for (uint32_t ii = 0; ii < _count; ++ii)
+ {
+ result = sem_post(&m_handle);
+ BX_CHECK(0 == result, "sem_post failed. errno %d", errno);
+ }
+ BX_UNUSED(result);
+ }
+
+ bool Semaphore::wait(int32_t _msecs)
+ {
+# if BX_PLATFORM_NACL || BX_PLATFORM_OSX
+ BX_CHECK(-1 == _msecs, "NaCl and OSX don't support sem_timedwait at this moment."); BX_UNUSED(_msecs);
+ return 0 == sem_wait(&m_handle);
+# else
+ if (0 > _msecs)
+ {
+ int32_t result;
+ do
+ {
+ result = sem_wait(&m_handle);
+ } // keep waiting when interrupted by a signal handler...
+ while (-1 == result && EINTR == errno);
+ BX_CHECK(0 == result, "sem_wait failed. errno %d", errno);
+ return 0 == result;
+ }
+
+ timespec ts;
+ clock_gettime(CLOCK_REALTIME, &ts);
+ ts.tv_sec += _msecs/1000;
+ ts.tv_nsec += (_msecs%1000)*1000;
+ return 0 == sem_timedwait(&m_handle, &ts);
+# endif // BX_PLATFORM_
+ }
+# endif // BX_CONFIG_SEMAPHORE_PTHREAD
+
+#elif BX_PLATFORM_XBOX360 || BX_PLATFORM_XBOXONE || BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT
+
+ Semaphore::Semaphore()
+ {
+#if BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT
+ m_handle = CreateSemaphoreExW(NULL, 0, LONG_MAX, NULL, 0, SEMAPHORE_ALL_ACCESS);
+#else
+ m_handle = CreateSemaphoreA(NULL, 0, LONG_MAX, NULL);
+#endif
+ BX_CHECK(NULL != m_handle, "Failed to create Semaphore!");
+ }
+
+ Semaphore::~Semaphore()
+ {
+ CloseHandle(m_handle);
+ }
+
+ void Semaphore::post(uint32_t _count)
+ {
+ ReleaseSemaphore(m_handle, _count, NULL);
+ }
+
+ bool Semaphore::wait(int32_t _msecs)
+ {
+ DWORD milliseconds = (0 > _msecs) ? INFINITE : _msecs;
+#if BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT
+ return WAIT_OBJECT_0 == WaitForSingleObjectEx(m_handle, milliseconds, FALSE);
+#else
+ return WAIT_OBJECT_0 == WaitForSingleObject(m_handle, milliseconds);
+#endif
+ }
+#endif // BX_PLATFORM_
+
+} // namespace bx
+
+#endif // BX_CONFIG_SUPPORTS_THREADING
diff --git a/3rdparty/bx/src/string.cpp b/3rdparty/bx/src/string.cpp
new file mode 100644
index 00000000000..c53a9de1155
--- /dev/null
+++ b/3rdparty/bx/src/string.cpp
@@ -0,0 +1,515 @@
+/*
+ * Copyright 2010-2017 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ */
+
+#include <bx/allocator.h>
+#include <bx/hash.h>
+#include <bx/readerwriter.h>
+#include <bx/string.h>
+
+#if !BX_CRT_NONE
+# include <stdio.h> // vsnprintf, vsnwprintf
+#endif // !BX_CRT_NONE
+
+namespace bx
+{
+ bool isSpace(char _ch)
+ {
+ return ' ' == _ch
+ || '\t' == _ch
+ || '\n' == _ch
+ || '\v' == _ch
+ || '\f' == _ch
+ || '\r' == _ch
+ ;
+ }
+
+ bool isUpper(char _ch)
+ {
+ return _ch >= 'A' && _ch <= 'Z';
+ }
+
+ bool isLower(char _ch)
+ {
+ return _ch >= 'a' && _ch <= 'z';
+ }
+
+ bool isAlpha(char _ch)
+ {
+ return isLower(_ch) || isUpper(_ch);
+ }
+
+ bool isNumeric(char _ch)
+ {
+ return _ch >= '0' && _ch <= '9';
+ }
+
+ bool isAlphaNum(char _ch)
+ {
+ return isAlpha(_ch) || isNumeric(_ch);
+ }
+
+ bool isPrint(char _ch)
+ {
+ return isAlphaNum(_ch) || isSpace(_ch);
+ }
+
+ char toLower(char _ch)
+ {
+ return _ch + (isUpper(_ch) ? 0x20 : 0);
+ }
+
+ char toUpper(char _ch)
+ {
+ return _ch - (isLower(_ch) ? 0x20 : 0);
+ }
+
+ bool toBool(const char* _str)
+ {
+ char ch = toLower(_str[0]);
+ return ch == 't' || ch == '1';
+ }
+
+ int32_t strncmp(const char* _lhs, const char* _rhs, size_t _max)
+ {
+ for (
+ ; 0 < _max && *_lhs == *_rhs
+ ; ++_lhs, ++_rhs, --_max
+ )
+ {
+ if (*_lhs == '\0'
+ || *_rhs == '\0')
+ {
+ break;
+ }
+ }
+
+ return 0 == _max ? 0 : *_lhs - *_rhs;
+ }
+
+ int32_t strincmp(const char* _lhs, const char* _rhs, size_t _max)
+ {
+ for (
+ ; 0 < _max && toLower(*_lhs) == toLower(*_rhs)
+ ; ++_lhs, ++_rhs, --_max
+ )
+ {
+ if (*_lhs == '\0'
+ || *_rhs == '\0')
+ {
+ break;
+ }
+ }
+
+ return 0 == _max ? 0 : *_lhs - *_rhs;
+ }
+
+ size_t strnlen(const char* _str, size_t _max)
+ {
+ const char* ptr;
+ for (ptr = _str; 0 < _max && *ptr != '\0'; ++ptr, --_max) {};
+ return ptr - _str;
+ }
+
+ size_t strlncpy(char* _dst, size_t _dstSize, const char* _src, size_t _num)
+ {
+ BX_CHECK(NULL != _dst, "_dst can't be NULL!");
+ BX_CHECK(NULL != _src, "_src can't be NULL!");
+ BX_CHECK(0 < _dstSize, "_dstSize can't be 0!");
+
+ const size_t len = strnlen(_src, _num);
+ const size_t max = _dstSize-1;
+ const size_t num = (len < max ? len : max);
+ memcpy(_dst, _src, num);
+ _dst[num] = '\0';
+
+ return num;
+ }
+
+ size_t strlncat(char* _dst, size_t _dstSize, const char* _src, size_t _num)
+ {
+ BX_CHECK(NULL != _dst, "_dst can't be NULL!");
+ BX_CHECK(NULL != _src, "_src can't be NULL!");
+ BX_CHECK(0 < _dstSize, "_dstSize can't be 0!");
+
+ const size_t max = _dstSize;
+ const size_t len = strnlen(_dst, max);
+ return strlncpy(&_dst[len], max-len, _src, _num);
+ }
+
+ const char* strnchr(const char* _str, char _ch, size_t _max)
+ {
+ for (size_t ii = 0, len = strnlen(_str, _max); ii < len; ++ii)
+ {
+ if (_str[ii] == _ch)
+ {
+ return &_str[ii];
+ }
+ }
+
+ return NULL;
+ }
+
+ const char* strnrchr(const char* _str, char _ch, size_t _max)
+ {
+ for (size_t ii = strnlen(_str, _max); 0 < ii; --ii)
+ {
+ if (_str[ii] == _ch)
+ {
+ return &_str[ii];
+ }
+ }
+
+ return NULL;
+ }
+
+ const char* strnstr(const char* _str, const char* _find, size_t _max)
+ {
+ const char* ptr = _str;
+
+ size_t stringLen = strnlen(_str, _max);
+ const size_t findLen = strnlen(_find);
+
+ for (; stringLen >= findLen; ++ptr, --stringLen)
+ {
+ // Find start of the string.
+ while (*ptr != *_find)
+ {
+ ++ptr;
+ --stringLen;
+
+ // Search pattern lenght can't be longer than the string.
+ if (findLen > stringLen)
+ {
+ return NULL;
+ }
+ }
+
+ // Set pointers.
+ const char* string = ptr;
+ const char* search = _find;
+
+ // Start comparing.
+ while (*string++ == *search++)
+ {
+ // If end of the 'search' string is reached, all characters match.
+ if ('\0' == *search)
+ {
+ return ptr;
+ }
+ }
+ }
+
+ return NULL;
+ }
+
+ const char* stristr(const char* _str, const char* _find, size_t _max)
+ {
+ const char* ptr = _str;
+
+ size_t stringLen = strnlen(_str, _max);
+ const size_t findLen = strnlen(_find);
+
+ for (; stringLen >= findLen; ++ptr, --stringLen)
+ {
+ // Find start of the string.
+ while (toLower(*ptr) != toLower(*_find) )
+ {
+ ++ptr;
+ --stringLen;
+
+ // Search pattern lenght can't be longer than the string.
+ if (findLen > stringLen)
+ {
+ return NULL;
+ }
+ }
+
+ // Set pointers.
+ const char* string = ptr;
+ const char* search = _find;
+
+ // Start comparing.
+ while (toLower(*string++) == toLower(*search++) )
+ {
+ // If end of the 'search' string is reached, all characters match.
+ if ('\0' == *search)
+ {
+ return ptr;
+ }
+ }
+ }
+
+ return NULL;
+ }
+
+ const char* strnl(const char* _str)
+ {
+ for (; '\0' != *_str; _str += strnlen(_str, 1024) )
+ {
+ const char* eol = strnstr(_str, "\r\n", 1024);
+ if (NULL != eol)
+ {
+ return eol + 2;
+ }
+
+ eol = strnstr(_str, "\n", 1024);
+ if (NULL != eol)
+ {
+ return eol + 1;
+ }
+ }
+
+ return _str;
+ }
+
+ const char* streol(const char* _str)
+ {
+ for (; '\0' != *_str; _str += strnlen(_str, 1024) )
+ {
+ const char* eol = strnstr(_str, "\r\n", 1024);
+ if (NULL != eol)
+ {
+ return eol;
+ }
+
+ eol = strnstr(_str, "\n", 1024);
+ if (NULL != eol)
+ {
+ return eol;
+ }
+ }
+
+ return _str;
+ }
+
+ const char* strws(const char* _str)
+ {
+ for (; isSpace(*_str); ++_str) {};
+ return _str;
+ }
+
+ const char* strnws(const char* _str)
+ {
+ for (; !isSpace(*_str); ++_str) {};
+ return _str;
+ }
+
+ const char* strword(const char* _str)
+ {
+ for (char ch = *_str++; isAlphaNum(ch) || '_' == ch; ch = *_str++) {};
+ return _str-1;
+ }
+
+ const char* strmb(const char* _str, char _open, char _close)
+ {
+ int count = 0;
+ for (char ch = *_str++; ch != '\0' && count >= 0; ch = *_str++)
+ {
+ if (ch == _open)
+ {
+ count++;
+ }
+ else if (ch == _close)
+ {
+ count--;
+ if (0 == count)
+ {
+ return _str-1;
+ }
+ }
+ }
+
+ return NULL;
+ }
+
+ void eolLF(char* _out, size_t _size, const char* _str)
+ {
+ if (0 < _size)
+ {
+ char* end = _out + _size - 1;
+ for (char ch = *_str++; ch != '\0' && _out < end; ch = *_str++)
+ {
+ if ('\r' != ch)
+ {
+ *_out++ = ch;
+ }
+ }
+
+ *_out = '\0';
+ }
+ }
+
+ const char* findIdentifierMatch(const char* _str, const char* _word)
+ {
+ size_t len = strnlen(_word);
+ const char* ptr = strnstr(_str, _word);
+ for (; NULL != ptr; ptr = strnstr(ptr + len, _word) )
+ {
+ if (ptr != _str)
+ {
+ char ch = *(ptr - 1);
+ if (isAlphaNum(ch) || '_' == ch)
+ {
+ continue;
+ }
+ }
+
+ char ch = ptr[len];
+ if (isAlphaNum(ch) || '_' == ch)
+ {
+ continue;
+ }
+
+ return ptr;
+ }
+
+ return ptr;
+ }
+
+ const char* findIdentifierMatch(const char* _str, const char* _words[])
+ {
+ for (const char* word = *_words; NULL != word; ++_words, word = *_words)
+ {
+ const char* match = findIdentifierMatch(_str, word);
+ if (NULL != match)
+ {
+ return match;
+ }
+ }
+
+ return NULL;
+ }
+
+ int32_t write(WriterI* _writer, const char* _format, va_list _argList, Error* _err);
+
+ int32_t vsnprintfRef(char* _out, size_t _max, const char* _format, va_list _argList)
+ {
+ if (1 < _max)
+ {
+ StaticMemoryBlockWriter writer(_out, _max-1);
+ _out[_max-1] = '\0';
+
+ Error err;
+ va_list argListCopy;
+ va_copy(argListCopy, _argList);
+ int32_t size = write(&writer, _format, argListCopy, &err);
+ va_end(argListCopy);
+
+ if (err.isOk() )
+ {
+ return size;
+ }
+ }
+
+ Error err;
+ SizerWriter sizer;
+ va_list argListCopy;
+ va_copy(argListCopy, _argList);
+ int32_t size = write(&sizer, _format, argListCopy, &err);
+ va_end(argListCopy);
+
+ return size - 1 /* size without '\0' terminator */;
+ }
+
+ int32_t vsnprintf(char* _out, size_t _max, const char* _format, va_list _argList)
+ {
+#if BX_CRT_NONE
+ return vsnprintfRef(_out, _max, _format, _argList);
+#elif BX_CRT_MSVC
+ int32_t len = -1;
+ if (NULL != _out)
+ {
+ va_list argListCopy;
+ va_copy(argListCopy, _argList);
+ len = ::vsnprintf_s(_out, _max, size_t(-1), _format, argListCopy);
+ va_end(argListCopy);
+ }
+ return -1 == len ? ::_vscprintf(_format, _argList) : len;
+#else
+ return ::vsnprintf(_out, _max, _format, _argList);
+#endif // BX_COMPILER_MSVC
+ }
+
+ int32_t snprintf(char* _out, size_t _max, const char* _format, ...)
+ {
+ va_list argList;
+ va_start(argList, _format);
+ int32_t len = vsnprintf(_out, _max, _format, argList);
+ va_end(argList);
+ return len;
+ }
+
+ int32_t vsnwprintf(wchar_t* _out, size_t _max, const wchar_t* _format, va_list _argList)
+ {
+#if BX_CRT_NONE
+ BX_UNUSED(_out, _max, _format, _argList);
+ return 0;
+#elif BX_CRT_MSVC
+ int32_t len = -1;
+ if (NULL != _out)
+ {
+ va_list argListCopy;
+ va_copy(argListCopy, _argList);
+ len = ::_vsnwprintf_s(_out, _max, size_t(-1), _format, argListCopy);
+ va_end(argListCopy);
+ }
+ return -1 == len ? ::_vscwprintf(_format, _argList) : len;
+#elif BX_CRT_MINGW
+ return ::vsnwprintf(_out, _max, _format, _argList);
+#else
+ return ::vswprintf(_out, _max, _format, _argList);
+#endif // BX_COMPILER_MSVC
+ }
+
+ int32_t swnprintf(wchar_t* _out, size_t _max, const wchar_t* _format, ...)
+ {
+ va_list argList;
+ va_start(argList, _format);
+ int32_t len = vsnwprintf(_out, _max, _format, argList);
+ va_end(argList);
+ return len;
+ }
+
+ const char* baseName(const char* _filePath)
+ {
+ const char* bs = strnrchr(_filePath, '\\');
+ const char* fs = strnrchr(_filePath, '/');
+ const char* slash = (bs > fs ? bs : fs);
+ const char* colon = strnrchr(_filePath, ':');
+ const char* basename = slash > colon ? slash : colon;
+ if (NULL != basename)
+ {
+ return basename+1;
+ }
+
+ return _filePath;
+ }
+
+ void prettify(char* _out, size_t _count, uint64_t _size)
+ {
+ uint8_t idx = 0;
+ double size = double(_size);
+ while (_size != (_size&0x7ff)
+ && idx < 9)
+ {
+ _size >>= 10;
+ size *= 1.0/1024.0;
+ ++idx;
+ }
+
+ snprintf(_out, _count, "%0.2f %c%c", size, "BkMGTPEZY"[idx], idx > 0 ? 'B' : '\0');
+ }
+
+ size_t strlcpy(char* _dst, const char* _src, size_t _max)
+ {
+ return strlncpy(_dst, _max, _src);
+ }
+
+ size_t strlcat(char* _dst, const char* _src, size_t _max)
+ {
+ return strlncat(_dst, _max, _src);
+ }
+
+} // namespace bx
diff --git a/3rdparty/bx/src/thread.cpp b/3rdparty/bx/src/thread.cpp
new file mode 100644
index 00000000000..fea7e8b606c
--- /dev/null
+++ b/3rdparty/bx/src/thread.cpp
@@ -0,0 +1,208 @@
+/*
+ * Copyright 2010-2017 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ */
+
+#include <bx/thread.h>
+
+#if BX_CONFIG_SUPPORTS_THREADING
+
+namespace bx
+{
+ Thread::Thread()
+#if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 || BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT
+ : m_handle(INVALID_HANDLE_VALUE)
+ , m_threadId(UINT32_MAX)
+#elif BX_PLATFORM_POSIX
+ : m_handle(0)
+#endif // BX_PLATFORM_
+ , m_fn(NULL)
+ , m_userData(NULL)
+ , m_stackSize(0)
+ , m_exitCode(0 /*EXIT_SUCCESS*/)
+ , m_running(false)
+ {
+ }
+
+ Thread::~Thread()
+ {
+ if (m_running)
+ {
+ shutdown();
+ }
+ }
+
+ void Thread::init(ThreadFn _fn, void* _userData, uint32_t _stackSize, const char* _name)
+ {
+ BX_CHECK(!m_running, "Already running!");
+
+ m_fn = _fn;
+ m_userData = _userData;
+ m_stackSize = _stackSize;
+ m_running = true;
+
+#if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 || BX_PLATFORM_XBOXONE
+ m_handle = ::CreateThread(NULL
+ , m_stackSize
+ , (LPTHREAD_START_ROUTINE)threadFunc
+ , this
+ , 0
+ , NULL
+ );
+#elif BX_PLATFORM_WINRT
+ m_handle = CreateEventEx(nullptr, nullptr, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS);
+ auto workItemHandler = ref new WorkItemHandler([=](IAsyncAction^)
+ {
+ m_exitCode = threadFunc(this);
+ SetEvent(m_handle);
+ }, CallbackContext::Any);
+
+ ThreadPool::RunAsync(workItemHandler, WorkItemPriority::Normal, WorkItemOptions::TimeSliced);
+#elif BX_PLATFORM_POSIX
+ int result;
+ BX_UNUSED(result);
+
+ pthread_attr_t attr;
+ result = pthread_attr_init(&attr);
+ BX_CHECK(0 == result, "pthread_attr_init failed! %d", result);
+
+ if (0 != m_stackSize)
+ {
+ result = pthread_attr_setstacksize(&attr, m_stackSize);
+ BX_CHECK(0 == result, "pthread_attr_setstacksize failed! %d", result);
+ }
+
+ // sched_param sched;
+ // sched.sched_priority = 0;
+ // result = pthread_attr_setschedparam(&attr, &sched);
+ // BX_CHECK(0 == result, "pthread_attr_setschedparam failed! %d", result);
+
+ result = pthread_create(&m_handle, &attr, &threadFunc, this);
+ BX_CHECK(0 == result, "pthread_attr_setschedparam failed! %d", result);
+#else
+# error "Not implemented!"
+#endif // BX_PLATFORM_
+
+ m_sem.wait();
+
+ if (NULL != _name)
+ {
+ setThreadName(_name);
+ }
+ }
+
+ void Thread::shutdown()
+ {
+ BX_CHECK(m_running, "Not running!");
+#if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360
+ WaitForSingleObject(m_handle, INFINITE);
+ GetExitCodeThread(m_handle, (DWORD*)&m_exitCode);
+ CloseHandle(m_handle);
+ m_handle = INVALID_HANDLE_VALUE;
+#elif BX_PLATFORM_WINRT
+ WaitForSingleObjectEx(m_handle, INFINITE, FALSE);
+ CloseHandle(m_handle);
+ m_handle = INVALID_HANDLE_VALUE;
+#elif BX_PLATFORM_POSIX
+ union
+ {
+ void* ptr;
+ int32_t i;
+ } cast;
+ pthread_join(m_handle, &cast.ptr);
+ m_exitCode = cast.i;
+ m_handle = 0;
+#endif // BX_PLATFORM_
+ m_running = false;
+ }
+
+ bool Thread::isRunning() const
+ {
+ return m_running;
+ }
+
+ int32_t Thread::getExitCode() const
+ {
+ return m_exitCode;
+ }
+
+ void Thread::setThreadName(const char* _name)
+ {
+#if BX_PLATFORM_OSX || BX_PLATFORM_IOS
+ pthread_setname_np(_name);
+#elif (BX_CRT_GLIBC >= 21200) && ! BX_PLATFORM_HURD
+ pthread_setname_np(m_handle, _name);
+#elif BX_PLATFORM_LINUX
+ prctl(PR_SET_NAME,_name, 0, 0, 0);
+#elif BX_PLATFORM_BSD
+# ifdef __NetBSD__
+ pthread_setname_np(m_handle, "%s", (void*)_name);
+# else
+ pthread_set_name_np(m_handle, _name);
+# endif // __NetBSD__
+#elif BX_PLATFORM_WINDOWS && BX_COMPILER_MSVC
+# pragma pack(push, 8)
+ struct ThreadName
+ {
+ DWORD type;
+ LPCSTR name;
+ DWORD id;
+ DWORD flags;
+ };
+# pragma pack(pop)
+ ThreadName tn;
+ tn.type = 0x1000;
+ tn.name = _name;
+ tn.id = m_threadId;
+ tn.flags = 0;
+
+ __try
+ {
+ RaiseException(0x406d1388
+ , 0
+ , sizeof(tn)/4
+ , reinterpret_cast<ULONG_PTR*>(&tn)
+ );
+ }
+ __except(EXCEPTION_EXECUTE_HANDLER)
+ {
+ }
+#else
+ BX_UNUSED(_name);
+#endif // BX_PLATFORM_
+ }
+
+ int32_t Thread::entry()
+ {
+#if BX_PLATFORM_WINDOWS
+ m_threadId = ::GetCurrentThreadId();
+#endif // BX_PLATFORM_WINDOWS
+
+ m_sem.post();
+ return m_fn(m_userData);
+ }
+
+#if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 || BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT
+ DWORD WINAPI Thread::threadFunc(LPVOID _arg)
+ {
+ Thread* thread = (Thread*)_arg;
+ int32_t result = thread->entry();
+ return result;
+ }
+#else
+ void* Thread::threadFunc(void* _arg)
+ {
+ Thread* thread = (Thread*)_arg;
+ union
+ {
+ void* ptr;
+ int32_t i;
+ } cast;
+ cast.i = thread->entry();
+ return cast.ptr;
+ }
+#endif // BX_PLATFORM_
+
+} // namespace bx
+
+#endif // BX_CONFIG_SUPPORTS_THREADING
diff --git a/3rdparty/bx/tests/dbg.cpp b/3rdparty/bx/tests/dbg.cpp
deleted file mode 100644
index 58e3f034a86..00000000000
--- a/3rdparty/bx/tests/dbg.cpp
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright 2011-2017 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
- */
-
-#include <stdio.h>
-#include <stdint.h>
-#include <inttypes.h>
-#include <ctype.h> // isprint
-
-#include "dbg.h"
-#include <bx/string.h>
-#include <bx/debug.h>
-
-void dbgPrintfVargs(const char* _format, va_list _argList)
-{
- char temp[8192];
- char* out = temp;
- int32_t len = bx::vsnprintf(out, sizeof(temp), _format, _argList);
- if ( (int32_t)sizeof(temp) < len)
- {
- out = (char*)alloca(len+1);
- len = bx::vsnprintf(out, len, _format, _argList);
- }
- out[len] = '\0';
- bx::debugOutput(out);
-}
-
-void dbgPrintf(const char* _format, ...)
-{
- va_list argList;
- va_start(argList, _format);
- dbgPrintfVargs(_format, argList);
- va_end(argList);
-}
-
-#define DBG_ADDRESS "%" PRIxPTR
-
-void dbgPrintfData(const void* _data, uint32_t _size, const char* _format, ...)
-{
-#define HEX_DUMP_WIDTH 16
-#define HEX_DUMP_SPACE_WIDTH 48
-#define HEX_DUMP_FORMAT "%-" DBG_STRINGIZE(HEX_DUMP_SPACE_WIDTH) "." DBG_STRINGIZE(HEX_DUMP_SPACE_WIDTH) "s"
-
- va_list argList;
- va_start(argList, _format);
- dbgPrintfVargs(_format, argList);
- va_end(argList);
-
- dbgPrintf("\ndata: " DBG_ADDRESS ", size: %d\n", _data, _size);
-
- if (NULL != _data)
- {
- const uint8_t* data = reinterpret_cast<const uint8_t*>(_data);
- char hex[HEX_DUMP_WIDTH*3+1];
- char ascii[HEX_DUMP_WIDTH+1];
- uint32_t hexPos = 0;
- uint32_t asciiPos = 0;
- for (uint32_t ii = 0; ii < _size; ++ii)
- {
- bx::snprintf(&hex[hexPos], sizeof(hex)-hexPos, "%02x ", data[asciiPos]);
- hexPos += 3;
-
- ascii[asciiPos] = isprint(data[asciiPos]) ? data[asciiPos] : '.';
- asciiPos++;
-
- if (HEX_DUMP_WIDTH == asciiPos)
- {
- ascii[asciiPos] = '\0';
- dbgPrintf("\t" DBG_ADDRESS "\t" HEX_DUMP_FORMAT "\t%s\n", data, hex, ascii);
- data += asciiPos;
- hexPos = 0;
- asciiPos = 0;
- }
- }
-
- if (0 != asciiPos)
- {
- ascii[asciiPos] = '\0';
- dbgPrintf("\t" DBG_ADDRESS "\t" HEX_DUMP_FORMAT "\t%s\n", data, hex, ascii);
- }
- }
-
-#undef HEX_DUMP_WIDTH
-#undef HEX_DUMP_SPACE_WIDTH
-#undef HEX_DUMP_FORMAT
-}
diff --git a/3rdparty/bx/tests/dbg.h b/3rdparty/bx/tests/dbg.h
index 21f4433820b..9ae46b35bbe 100644
--- a/3rdparty/bx/tests/dbg.h
+++ b/3rdparty/bx/tests/dbg.h
@@ -6,16 +6,11 @@
#ifndef DBG_H_HEADER_GUARD
#define DBG_H_HEADER_GUARD
-#include <stdarg.h> // va_list
-#include <stdint.h>
+#include <bx/debug.h>
#define DBG_STRINGIZE(_x) DBG_STRINGIZE_(_x)
#define DBG_STRINGIZE_(_x) #_x
#define DBG_FILE_LINE_LITERAL "" __FILE__ "(" DBG_STRINGIZE(__LINE__) "): "
-#define DBG(_format, ...) dbgPrintf(DBG_FILE_LINE_LITERAL "" _format "\n", ##__VA_ARGS__)
-
-extern void dbgPrintfVargs(const char* _format, va_list _argList);
-extern void dbgPrintf(const char* _format, ...);
-extern void dbgPrintfData(const void* _data, uint32_t _size, const char* _format, ...);
+#define DBG(_format, ...) bx::debugPrintf(DBG_FILE_LINE_LITERAL "" _format "\n", ##__VA_ARGS__)
#endif // DBG_H_HEADER_GUARD
diff --git a/3rdparty/bx/tests/fpumath_test.cpp b/3rdparty/bx/tests/fpumath_test.cpp
index f41cea8ba91..ae843872e43 100644
--- a/3rdparty/bx/tests/fpumath_test.cpp
+++ b/3rdparty/bx/tests/fpumath_test.cpp
@@ -6,6 +6,26 @@
#include "test.h"
#include <bx/fpumath.h>
+#if !BX_COMPILER_MSVC || BX_COMPILER_MSVC >= 1800
+#include <cmath>
+TEST_CASE("isFinite, isInfinite, isNan", "")
+{
+ for (uint64_t ii = 0; ii < UINT32_MAX; ii += rand()%(1<<13)+1)
+ {
+ union { uint32_t ui; float f; } u = { uint32_t(ii) };
+ REQUIRE(std::isnan(u.f) == bx::isNan(u.f) );
+ REQUIRE(std::isfinite(u.f) == bx::isFinite(u.f) );
+ REQUIRE(std::isinf(u.f) == bx::isInfinite(u.f) );
+ }
+}
+#endif // !BX_COMPILER_MSVC || BX_COMPILER_MSVC >= 1800
+
+TEST_CASE("ToBits", "")
+{
+ REQUIRE(UINT32_C(0x12345678) == bx::floatToBits( bx::bitsToFloat( UINT32_C(0x12345678) ) ) );
+ REQUIRE(UINT64_C(0x123456789abcdef0) == bx::doubleToBits(bx::bitsToDouble(UINT32_C(0x123456789abcdef0) ) ) );
+}
+
void mtxCheck(const float* _a, const float* _b)
{
if (!bx::fequal(_a, _b, 16, 0.01f) )
@@ -35,7 +55,7 @@ void mtxCheck(const float* _a, const float* _b)
}
}
-TEST(Quaternion)
+TEST_CASE("quaternion", "")
{
float mtxQ[16];
float mtx[16];
diff --git a/3rdparty/bx/tests/handle_bench.cpp b/3rdparty/bx/tests/handle_bench.cpp
index a882cbe635d..6169bc45c53 100644
--- a/3rdparty/bx/tests/handle_bench.cpp
+++ b/3rdparty/bx/tests/handle_bench.cpp
@@ -28,13 +28,13 @@ int main()
for (uint32_t jj = 0; jj < numElements; ++jj)
{
tinystl::pair<TinyStlUnorderedMap::iterator, bool> ok = map.insert(tinystl::make_pair(uint64_t(jj), uint16_t(jj) ) );
- assert(ok.second);
+ assert(ok.second); BX_UNUSED(ok);
}
for (uint32_t jj = 0; jj < numElements; ++jj)
{
bool ok = bx::mapRemove(map, uint64_t(jj) );
- assert(ok);
+ assert(ok); BX_UNUSED(ok);
}
assert(map.size() == 0);
@@ -56,13 +56,13 @@ int main()
for (uint32_t jj = 0; jj < numElements; ++jj)
{
std::pair<StdUnorderedMap::iterator, bool> ok = map.insert(std::make_pair(uint64_t(jj), uint16_t(jj) ) );
- assert(ok.second);
+ assert(ok.second); BX_UNUSED(ok);
}
for (uint32_t jj = 0; jj < numElements; ++jj)
{
bool ok = bx::mapRemove(map, uint64_t(jj) );
- assert(ok);
+ assert(ok); BX_UNUSED(ok);
}
assert(map.size() == 0);
@@ -83,13 +83,13 @@ int main()
for (uint32_t jj = 0; jj < numElements; ++jj)
{
bool ok = map.insert(jj, uint16_t(jj) );
- assert(ok);
+ assert(ok); BX_UNUSED(ok);
}
for (uint32_t jj = 0; jj < numElements; ++jj)
{
bool ok = map.removeByKey(uint64_t(jj) );
- assert(ok);
+ assert(ok); BX_UNUSED(ok);
}
assert(map.getNumElements() == 0);
diff --git a/3rdparty/bx/tests/misc_test.cpp b/3rdparty/bx/tests/misc_test.cpp
deleted file mode 100644
index aec1067a022..00000000000
--- a/3rdparty/bx/tests/misc_test.cpp
+++ /dev/null
@@ -1,8 +0,0 @@
-#include "test.h"
-#include <bx/os.h>
-
-TEST(getProcessMemoryUsed)
-{
- CHECK(0 != bx::getProcessMemoryUsed() );
-// DBG("bx::getProcessMemoryUsed %d", bx::getProcessMemoryUsed() );
-}
diff --git a/3rdparty/bx/tests/os_test.cpp b/3rdparty/bx/tests/os_test.cpp
new file mode 100644
index 00000000000..e6aeb314fbe
--- /dev/null
+++ b/3rdparty/bx/tests/os_test.cpp
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2010-2017 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ */
+
+#include "test.h"
+#include <bx/os.h>
+
+TEST_CASE("getProcessMemoryUsed", "")
+{
+ REQUIRE(0 != bx::getProcessMemoryUsed() );
+// DBG("bx::getProcessMemoryUsed %d", bx::getProcessMemoryUsed() );
+}
+
+TEST_CASE("getTempPath", "")
+{
+ char tmpDir[512];
+ uint32_t len = BX_COUNTOF(tmpDir);
+ REQUIRE(bx::getTempPath(tmpDir, &len) );
+}
diff --git a/3rdparty/bx/tests/string_test.cpp b/3rdparty/bx/tests/string_test.cpp
index ed83e86cc4d..bea72044e54 100644
--- a/3rdparty/bx/tests/string_test.cpp
+++ b/3rdparty/bx/tests/string_test.cpp
@@ -10,6 +10,19 @@
bx::AllocatorI* g_allocator;
+TEST_CASE("chars", "")
+{
+ for (char ch = 'A'; ch <= 'Z'; ++ch)
+ {
+ REQUIRE(!bx::isLower(ch) );
+ REQUIRE(!bx::isNumeric(ch) );
+ REQUIRE(bx::isUpper(ch) );
+ REQUIRE(bx::isAlpha(ch) );
+ REQUIRE(bx::isAlphaNum(ch) );
+ REQUIRE(bx::isLower(bx::toLower(ch) ) );
+ }
+}
+
TEST_CASE("strnlen", "")
{
const char* test = "test";
@@ -40,6 +53,129 @@ TEST_CASE("strlncpy", "")
REQUIRE(num == 4);
}
+TEST_CASE("strlncat", "")
+{
+ char dst[128] = { '\0' };
+
+ REQUIRE(0 == bx::strlncat(dst, 1, "cat") );
+
+ REQUIRE(4 == bx::strlncpy(dst, 5, "copy") );
+ REQUIRE(3 == bx::strlncat(dst, 8, "cat") );
+ REQUIRE(0 == bx::strncmp(dst, "copycat") );
+
+ REQUIRE(1 == bx::strlncat(dst, BX_COUNTOF(dst), "------", 1) );
+ REQUIRE(3 == bx::strlncat(dst, BX_COUNTOF(dst), "cat") );
+ REQUIRE(0 == bx::strncmp(dst, "copycat-cat") );
+}
+
+TEST_CASE("strincmp", "")
+{
+ REQUIRE(0 == bx::strincmp("test", "test") );
+ REQUIRE(0 == bx::strincmp("test", "testestes", 4) );
+ REQUIRE(0 == bx::strincmp("testestes", "test", 4) );
+ REQUIRE(0 != bx::strincmp("preprocess", "platform") );
+
+ const char* abvgd = "abvgd";
+ const char* abvgx = "abvgx";
+ const char* empty = "";
+ REQUIRE(0 == bx::strincmp(abvgd, abvgd) );
+ REQUIRE(0 == bx::strincmp(abvgd, abvgx, 4) );
+
+ REQUIRE(0 > bx::strincmp(abvgd, abvgx) );
+ REQUIRE(0 > bx::strincmp(empty, abvgd) );
+
+ REQUIRE(0 < bx::strincmp(abvgx, abvgd) );
+ REQUIRE(0 < bx::strincmp(abvgd, empty) );
+}
+
+TEST_CASE("strnchr", "")
+{
+ const char* test = "test";
+ REQUIRE(NULL == bx::strnchr(test, 's', 0) );
+ REQUIRE(NULL == bx::strnchr(test, 's', 2) );
+ REQUIRE(&test[2] == bx::strnchr(test, 's') );
+}
+
+TEST_CASE("strnrchr", "")
+{
+ const char* test = "test";
+ REQUIRE(NULL == bx::strnrchr(test, 's', 0) );
+ REQUIRE(NULL == bx::strnrchr(test, 's', 1) );
+ REQUIRE(&test[2] == bx::strnrchr(test, 's') );
+}
+
+TEST_CASE("stristr", "")
+{
+ const char* test = "The Quick Brown Fox Jumps Over The Lazy Dog.";
+
+ REQUIRE(NULL == bx::stristr(test, "quick", 8) );
+ REQUIRE(NULL == bx::stristr(test, "quick1") );
+ REQUIRE(&test[4] == bx::stristr(test, "quick", 9) );
+ REQUIRE(&test[4] == bx::stristr(test, "quick") );
+}
+
+TEST_CASE("strnstr", "")
+{
+ const char* test = "The Quick Brown Fox Jumps Over The Lazy Dog.";
+
+ REQUIRE(NULL == bx::strnstr(test, "quick", 8) );
+ REQUIRE(NULL == bx::strnstr(test, "quick1") );
+ REQUIRE(NULL == bx::strnstr(test, "quick", 9) );
+ REQUIRE(NULL == bx::strnstr(test, "quick") );
+
+ REQUIRE(NULL == bx::strnstr(test, "Quick", 8) );
+ REQUIRE(NULL == bx::strnstr(test, "Quick1") );
+ REQUIRE(&test[4] == bx::strnstr(test, "Quick", 9) );
+ REQUIRE(&test[4] == bx::strnstr(test, "Quick") );
+}
+
+template<typename Ty>
+static bool testToString(Ty _value, const char* _expected)
+{
+ char tmp[1024];
+ int32_t num = bx::toString(tmp, BX_COUNTOF(tmp), _value);
+ int32_t len = (int32_t)bx::strnlen(_expected);
+ return true
+ && 0 == bx::strncmp(tmp, _expected)
+ && num == len
+ ;
+}
+
+TEST_CASE("toString int32_t/uint32_t", "")
+{
+ REQUIRE(testToString(0, "0") );
+ REQUIRE(testToString(-256, "-256") );
+ REQUIRE(testToString(INT32_MAX, "2147483647") );
+ REQUIRE(testToString(UINT32_MAX, "4294967295") );
+}
+
+TEST_CASE("toString double", "")
+{
+ REQUIRE(testToString(0.0, "0.0") );
+ REQUIRE(testToString(-0.0, "0.0") );
+ REQUIRE(testToString(1.0, "1.0") );
+ REQUIRE(testToString(-1.0, "-1.0") );
+ REQUIRE(testToString(1.2345, "1.2345") );
+ REQUIRE(testToString(1.2345678, "1.2345678") );
+ REQUIRE(testToString(0.123456789012, "0.123456789012") );
+ REQUIRE(testToString(1234567.8, "1234567.8") );
+ REQUIRE(testToString(-79.39773355813419, "-79.39773355813419") );
+ REQUIRE(testToString(0.000001, "0.000001") );
+ REQUIRE(testToString(0.0000001, "1e-7") );
+ REQUIRE(testToString(1e30, "1e30") );
+ REQUIRE(testToString(1.234567890123456e30, "1.234567890123456e30") );
+ REQUIRE(testToString(-5e-324, "-5e-324") );
+ REQUIRE(testToString(2.225073858507201e-308, "2.225073858507201e-308") );
+ REQUIRE(testToString(2.2250738585072014e-308, "2.2250738585072014e-308") );
+ REQUIRE(testToString(1.7976931348623157e308, "1.7976931348623157e308") );
+ REQUIRE(testToString(0.00000123123123, "0.00000123123123") );
+ REQUIRE(testToString(0.000000123123123, "1.23123123e-7") );
+ REQUIRE(testToString(123123.123, "123123.123") );
+ REQUIRE(testToString(1231231.23, "1231231.23") );
+ REQUIRE(testToString(0.000000000123123, "1.23123e-10") );
+ REQUIRE(testToString(0.0000000001, "1e-10") );
+}
+
TEST_CASE("StringView", "")
{
bx::StringView sv("test");
diff --git a/3rdparty/bx/tests/test.h b/3rdparty/bx/tests/test.h
index 33c3cf7cbc0..db710195023 100644
--- a/3rdparty/bx/tests/test.h
+++ b/3rdparty/bx/tests/test.h
@@ -13,8 +13,4 @@
#include "dbg.h"
-#if !BX_COMPILER_MSVC
-# define _strdup strdup
-#endif // !BX_COMPILER_MSVC
-
#endif // __TEST_H__
diff --git a/3rdparty/bx/tests/tokenizecmd_test.cpp b/3rdparty/bx/tests/tokenizecmd_test.cpp
index 12502502a1a..7d35ac7484c 100644
--- a/3rdparty/bx/tests/tokenizecmd_test.cpp
+++ b/3rdparty/bx/tests/tokenizecmd_test.cpp
@@ -4,7 +4,6 @@
*/
#include "test.h"
-#include <bx/tokenizecmd.h>
#include <bx/commandline.h>
#include <string.h>
@@ -14,6 +13,8 @@ TEST(commandLine)
{
"-s",
"--long",
+ "--platform",
+ "x",
};
bx::CommandLine cmdLine(BX_COUNTOF(args), args);
@@ -23,6 +24,7 @@ TEST(commandLine)
// non-existing argument
CHECK(!cmdLine.hasArg('x') );
+ CHECK(!cmdLine.hasArg("preprocess") );
}
TEST(tokenizeCommandLine)
diff --git a/3rdparty/bx/tests/uint32_test.cpp b/3rdparty/bx/tests/uint32_test.cpp
index 0c2be1e9cb7..ae214b88c22 100644
--- a/3rdparty/bx/tests/uint32_test.cpp
+++ b/3rdparty/bx/tests/uint32_test.cpp
@@ -6,47 +6,66 @@
#include "test.h"
#include <bx/uint32_t.h>
-TEST(StrideAlign)
+TEST_CASE("StrideAlign")
{
- CHECK(0 == bx::strideAlign(0, 12) );
+ REQUIRE(0 == bx::strideAlign(0, 12) );
for (uint32_t ii = 0; ii < 12; ++ii)
{
- CHECK(12 == bx::strideAlign(ii+1, 12) );
+ REQUIRE(12 == bx::strideAlign(ii+1, 12) );
}
- CHECK(0 == bx::strideAlign16(0, 12) );
+ REQUIRE(0 == bx::strideAlign16(0, 12) );
for (uint32_t ii = 0; ii < 12; ++ii)
{
- CHECK(48 == bx::strideAlign16(ii+1, 12) );
+ REQUIRE(48 == bx::strideAlign16(ii+1, 12) );
}
}
-TEST(uint32_cnt)
+TEST_CASE("uint32_cnt")
{
- CHECK( 0 == bx::uint32_cnttz(UINT32_C(1) ) );
- CHECK( 0 == bx::uint32_cnttz_ref(UINT32_C(1) ) );
+ REQUIRE( 0 == bx::uint32_cnttz(UINT32_C(1) ) );
+ REQUIRE( 0 == bx::uint32_cnttz_ref(UINT32_C(1) ) );
- CHECK(31 == bx::uint32_cntlz(UINT32_C(1) ) );
- CHECK(31 == bx::uint32_cntlz_ref(UINT32_C(1) ) );
+ REQUIRE(31 == bx::uint32_cntlz(UINT32_C(1) ) );
+ REQUIRE(31 == bx::uint32_cntlz_ref(UINT32_C(1) ) );
- CHECK( 0 == bx::uint64_cnttz(UINT64_C(1) ) );
- CHECK( 0 == bx::uint64_cnttz_ref(UINT64_C(1) ) );
+ REQUIRE( 0 == bx::uint64_cnttz(UINT64_C(1) ) );
+ REQUIRE( 0 == bx::uint64_cnttz_ref(UINT64_C(1) ) );
- CHECK(63 == bx::uint64_cntlz(UINT64_C(1) ) );
- CHECK(63 == bx::uint64_cntlz_ref(UINT64_C(1) ) );
+ REQUIRE(63 == bx::uint64_cntlz(UINT64_C(1) ) );
+ REQUIRE(63 == bx::uint64_cntlz_ref(UINT64_C(1) ) );
- CHECK( 1 == bx::uint32_cntbits(1) );
- CHECK( 1 == bx::uint32_cntbits_ref(1) );
+ REQUIRE( 1 == bx::uint32_cntbits(1) );
+ REQUIRE( 1 == bx::uint32_cntbits_ref(1) );
- CHECK(16 == bx::uint32_cntbits(UINT16_MAX) );
- CHECK(16 == bx::uint32_cntbits_ref(UINT16_MAX) );
+ REQUIRE(16 == bx::uint32_cntbits(UINT16_MAX) );
+ REQUIRE(16 == bx::uint32_cntbits_ref(UINT16_MAX) );
- CHECK(32 == bx::uint32_cntbits(UINT32_MAX) );
- CHECK(32 == bx::uint32_cntbits_ref(UINT32_MAX) );
+ REQUIRE(32 == bx::uint32_cntbits(UINT32_MAX) );
+ REQUIRE(32 == bx::uint32_cntbits_ref(UINT32_MAX) );
}
-TEST(uint32_part)
+TEST_CASE("uint32_part")
{
- CHECK(UINT32_C(0x55555555) == bx::uint32_part1by1(UINT16_MAX) );
- CHECK(UINT32_C(0x09249249) == bx::uint32_part1by2(0x3ff) );
+ REQUIRE(UINT32_C(0x55555555) == bx::uint32_part1by1(UINT16_MAX) );
+ REQUIRE(UINT32_C(0x09249249) == bx::uint32_part1by2(0x3ff) );
+}
+
+TEST_CASE("halfTo/FromFloat", "")
+{
+ for (uint32_t ii = 0; ii < 0x7c00; ++ii)
+ {
+ const uint16_t orig = uint16_t(ii);
+ const float htf = bx::halfToFloat(orig);
+ const uint16_t hff = bx::halfFromFloat(htf);
+ REQUIRE(orig == hff);
+ }
+
+ for (uint32_t ii = 0x8000; ii < 0xfc00; ++ii)
+ {
+ const uint16_t orig = uint16_t(ii);
+ const float htf = bx::halfToFloat(orig);
+ const uint16_t hff = bx::halfFromFloat(htf);
+ REQUIRE(orig == hff);
+ }
}
diff --git a/3rdparty/bx/tests/vector_complex_test.cpp b/3rdparty/bx/tests/vector_complex_test.cpp
index 8deaa3fd3ff..a540ece8a40 100644
--- a/3rdparty/bx/tests/vector_complex_test.cpp
+++ b/3rdparty/bx/tests/vector_complex_test.cpp
@@ -33,6 +33,10 @@
#include <string.h>
#include <stdlib.h>
+#if !BX_COMPILER_MSVC
+# define _strdup strdup
+#endif // !BX_COMPILER_MSVC
+
struct complex {
complex() {data = 0;}
complex(const char* s) { data = strdup(s); }
@@ -156,7 +160,7 @@ TEST(vector_complex_popback) {
v.push_back("24");
CHECK(v.back() == "24");
-
+
v.pop_back();
CHECK(v.back() == "12");
diff --git a/3rdparty/bx/tests/vsnprintf_test.cpp b/3rdparty/bx/tests/vsnprintf_test.cpp
new file mode 100644
index 00000000000..db1fba6fdad
--- /dev/null
+++ b/3rdparty/bx/tests/vsnprintf_test.cpp
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2010-2017 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ */
+
+#include "test.h"
+#include <bx/string.h>
+
+TEST_CASE("vsnprintf NULL buffer", "No output buffer provided.")
+{
+ REQUIRE(4 == bx::snprintf(NULL, 0, "test") );
+
+ REQUIRE(1 == bx::snprintf(NULL, 0, "%d", 1) );
+}
+
+TEST_CASE("vsnprintf truncated", "Truncated output buffer.")
+{
+ char buffer[7];
+
+ REQUIRE(10 == bx::snprintf(buffer, BX_COUNTOF(buffer), "Ten chars!") );
+ REQUIRE(0 == strcmp(buffer, "Ten ch") );
+}
+
+static bool test(const char* _expected, const char* _format, ...)
+{
+ int32_t max = (int32_t)strlen(_expected) + 1;
+ char* temp = (char*)alloca(max);
+
+ va_list argList;
+ va_start(argList, _format);
+ int32_t len = bx::vsnprintf(temp, max, _format, argList);
+ va_end(argList);
+
+ bool result = true
+ && len == max-1
+ && 0 == strcmp(_expected, temp)
+ ;
+
+ if (!result)
+ {
+ printf("result (%d) %s, expected (%d) %s\n", len, temp, max-1, _expected);
+ }
+
+ return result;
+}
+
+TEST_CASE("vsnprintf f", "")
+{
+ REQUIRE(test("1.337", "%0.3f", 1.337) );
+ REQUIRE(test(" 13.370", "%8.3f", 13.37) );
+ REQUIRE(test(" 13.370", "%*.*f", 8, 3, 13.37) );
+ REQUIRE(test("13.370 ", "%-8.3f", 13.37) );
+ REQUIRE(test("13.370 ", "%*.*f", -8, 3, 13.37) );
+}
+
+TEST_CASE("vsnprintf d/u/x", "")
+{
+ REQUIRE(test("1337", "%d", 1337) );
+
+ REQUIRE(test("1337", "%x", 0x1337) );
+}
+
+TEST_CASE("vsnprintf", "")
+{
+ REQUIRE(test("x", "%c", 'x') );
+
+ REQUIRE(test("hello, world!", "%s, %s!", "hello", "world") );
+}
diff --git a/3rdparty/bx/tools/bin/darwin/genie b/3rdparty/bx/tools/bin/darwin/genie
index 842ca082bdf..97c6f1279b9 100755
--- a/3rdparty/bx/tools/bin/darwin/genie
+++ b/3rdparty/bx/tools/bin/darwin/genie
Binary files differ
diff --git a/3rdparty/bx/tools/bin/linux/genie b/3rdparty/bx/tools/bin/linux/genie
index 7feeebbd006..3fa52f00f4f 100755
--- a/3rdparty/bx/tools/bin/linux/genie
+++ b/3rdparty/bx/tools/bin/linux/genie
Binary files differ
diff --git a/3rdparty/bx/tools/bin/windows/genie.exe b/3rdparty/bx/tools/bin/windows/genie.exe
index ad7d65824d6..19d6f15c6cd 100644
--- a/3rdparty/bx/tools/bin/windows/genie.exe
+++ b/3rdparty/bx/tools/bin/windows/genie.exe
Binary files differ