summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/bx/include
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/bx/include')
-rw-r--r--3rdparty/bx/include/bx/allocator.h28
-rw-r--r--3rdparty/bx/include/bx/bounds.h526
-rw-r--r--3rdparty/bx/include/bx/bx.h207
-rw-r--r--3rdparty/bx/include/bx/commandline.h4
-rw-r--r--3rdparty/bx/include/bx/config.h12
-rw-r--r--3rdparty/bx/include/bx/constants.h70
-rw-r--r--3rdparty/bx/include/bx/cpu.h4
-rw-r--r--3rdparty/bx/include/bx/debug.h8
-rw-r--r--3rdparty/bx/include/bx/easing.h4
-rw-r--r--3rdparty/bx/include/bx/endian.h12
-rw-r--r--3rdparty/bx/include/bx/error.h69
-rw-r--r--3rdparty/bx/include/bx/file.h75
-rw-r--r--3rdparty/bx/include/bx/filepath.h34
-rw-r--r--3rdparty/bx/include/bx/float4x4_t.h26
-rw-r--r--3rdparty/bx/include/bx/handlealloc.h6
-rw-r--r--3rdparty/bx/include/bx/hash.h98
-rw-r--r--3rdparty/bx/include/bx/inline/allocator.inl16
-rw-r--r--3rdparty/bx/include/bx/inline/bounds.inl257
-rw-r--r--3rdparty/bx/include/bx/inline/bx.inl117
-rw-r--r--3rdparty/bx/include/bx/inline/cpu.inl57
-rw-r--r--3rdparty/bx/include/bx/inline/easing.inl4
-rw-r--r--3rdparty/bx/include/bx/inline/endian.inl10
-rw-r--r--3rdparty/bx/include/bx/inline/error.inl71
-rw-r--r--3rdparty/bx/include/bx/inline/float4x4_t.inl93
-rw-r--r--3rdparty/bx/include/bx/inline/handlealloc.inl14
-rw-r--r--3rdparty/bx/include/bx/inline/hash.inl182
-rw-r--r--3rdparty/bx/include/bx/inline/math.inl928
-rw-r--r--3rdparty/bx/include/bx/inline/mpscqueue.inl4
-rw-r--r--3rdparty/bx/include/bx/inline/mutex.inl4
-rw-r--r--3rdparty/bx/include/bx/inline/os.inl18
-rw-r--r--3rdparty/bx/include/bx/inline/pixelformat.inl56
-rw-r--r--3rdparty/bx/include/bx/inline/readerwriter.inl44
-rw-r--r--3rdparty/bx/include/bx/inline/ringbuffer.inl8
-rw-r--r--3rdparty/bx/include/bx/inline/rng.inl10
-rw-r--r--3rdparty/bx/include/bx/inline/simd128_langext.inl12
-rw-r--r--3rdparty/bx/include/bx/inline/simd128_neon.inl64
-rw-r--r--3rdparty/bx/include/bx/inline/simd128_ref.inl53
-rw-r--r--3rdparty/bx/include/bx/inline/simd128_sse.inl40
-rw-r--r--3rdparty/bx/include/bx/inline/simd128_swizzle.inl2
-rw-r--r--3rdparty/bx/include/bx/inline/simd256_avx.inl4
-rw-r--r--3rdparty/bx/include/bx/inline/simd256_ref.inl4
-rw-r--r--3rdparty/bx/include/bx/inline/simd_ni.inl13
-rw-r--r--3rdparty/bx/include/bx/inline/sort.inl172
-rw-r--r--3rdparty/bx/include/bx/inline/spscqueue.inl9
-rw-r--r--3rdparty/bx/include/bx/inline/string.inl182
-rw-r--r--3rdparty/bx/include/bx/inline/typetraits.inl462
-rw-r--r--3rdparty/bx/include/bx/inline/uint32_t.inl235
-rw-r--r--3rdparty/bx/include/bx/macros.h98
-rw-r--r--3rdparty/bx/include/bx/maputil.h4
-rw-r--r--3rdparty/bx/include/bx/math.h522
-rw-r--r--3rdparty/bx/include/bx/mpscqueue.h8
-rw-r--r--3rdparty/bx/include/bx/mutex.h6
-rw-r--r--3rdparty/bx/include/bx/os.h14
-rw-r--r--3rdparty/bx/include/bx/pixelformat.h14
-rw-r--r--3rdparty/bx/include/bx/platform.h126
-rw-r--r--3rdparty/bx/include/bx/process.h4
-rw-r--r--3rdparty/bx/include/bx/readerwriter.h145
-rw-r--r--3rdparty/bx/include/bx/ringbuffer.h10
-rw-r--r--3rdparty/bx/include/bx/rng.h8
-rw-r--r--3rdparty/bx/include/bx/semaphore.h5
-rw-r--r--3rdparty/bx/include/bx/settings.h8
-rw-r--r--3rdparty/bx/include/bx/simd_t.h12
-rw-r--r--3rdparty/bx/include/bx/sort.h277
-rw-r--r--3rdparty/bx/include/bx/spscqueue.h12
-rw-r--r--3rdparty/bx/include/bx/string.h126
-rw-r--r--3rdparty/bx/include/bx/thread.h19
-rw-r--r--3rdparty/bx/include/bx/timer.h4
-rw-r--r--3rdparty/bx/include/bx/typetraits.h285
-rw-r--r--3rdparty/bx/include/bx/uint32_t.h90
-rw-r--r--3rdparty/bx/include/bx/url.h4
-rw-r--r--3rdparty/bx/include/compat/linux/sal.h1
-rw-r--r--3rdparty/bx/include/compat/mingw/salieri.h16
-rw-r--r--3rdparty/bx/include/compat/msvc/dirent.h1044
73 files changed, 5426 insertions, 1764 deletions
diff --git a/3rdparty/bx/include/bx/allocator.h b/3rdparty/bx/include/bx/allocator.h
index cfd1475ab52..925441ee5ec 100644
--- a/3rdparty/bx/include/bx/allocator.h
+++ b/3rdparty/bx/include/bx/allocator.h
@@ -1,12 +1,13 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_ALLOCATOR_H_HEADER_GUARD
#define BX_ALLOCATOR_H_HEADER_GUARD
#include "bx.h"
+#include "uint32_t.h"
#if BX_CONFIG_ALLOCATOR_DEBUG
# define BX_ALLOC(_allocator, _size) bx::alloc(_allocator, _size, 0, __FILE__, __LINE__)
@@ -30,9 +31,14 @@
#define BX_NEW(_allocator, _type) BX_PLACEMENT_NEW(BX_ALLOC(_allocator, sizeof(_type) ), _type)
#define BX_ALIGNED_NEW(_allocator, _type, _align) BX_PLACEMENT_NEW(BX_ALIGNED_ALLOC(_allocator, sizeof(_type), _align), _type)
-#define BX_PLACEMENT_NEW(_ptr, _type) ::new(bx::PlacementNewTag(), _ptr) _type
+#define BX_PLACEMENT_NEW(_ptr, _type) ::new(bx::PlacementNew, _ptr) _type
-namespace bx { struct PlacementNewTag {}; }
+namespace bx
+{
+ struct PlacementNewTag {};
+ constexpr PlacementNewTag PlacementNew;
+
+} // namespace bx
void* operator new(size_t, bx::PlacementNewTag, void* _ptr);
void operator delete(void*, bx::PlacementNewTag, void*) throw();
@@ -46,13 +52,20 @@ namespace bx
///
virtual ~AllocatorI() = 0;
- /// Allocates, resizes memory block, or frees memory.
+ /// Allocates, resizes, or frees memory block.
///
- /// @param[in] _ptr If _ptr is NULL new block will be allocated.
+ /// @remark
+ /// - Allocate memory block: _ptr == NULL && size > 0
+ /// - Resize memory block: _ptr != NULL && size > 0
+ /// - Free memory block: _ptr != NULL && size == 0
+ ///
+ /// @param[in] _ptr If _ptr is NULL new block will be allocated. If _ptr is not-NULL, and
+ /// _size is not 0, memory block will be resized.
/// @param[in] _size If _ptr is set, and _size is 0, memory will be freed.
/// @param[in] _align Alignment.
/// @param[in] _file Debug file path info.
/// @param[in] _line Debug file line info.
+ ///
virtual void* realloc(
void* _ptr
, size_t _size
@@ -82,9 +95,6 @@ namespace bx
) override;
};
- /// 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
diff --git a/3rdparty/bx/include/bx/bounds.h b/3rdparty/bx/include/bx/bounds.h
new file mode 100644
index 00000000000..12201b45f92
--- /dev/null
+++ b/3rdparty/bx/include/bx/bounds.h
@@ -0,0 +1,526 @@
+/*
+ * Copyright 2011-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
+ */
+
+#ifndef BX_BOUNDS_H_HEADER_GUARD
+#define BX_BOUNDS_H_HEADER_GUARD
+
+#include <bx/math.h>
+
+namespace bx
+{
+ ///
+ struct Line
+ {
+ Vec3 pos = init::None;
+ Vec3 dir = init::None;
+ };
+
+ ///
+ struct LineSegment
+ {
+ Vec3 pos = init::None;
+ Vec3 end = init::None;
+ };
+
+ ///
+ struct Aabb
+ {
+ Vec3 min = init::None;
+ Vec3 max = init::None;
+ };
+
+ ///
+ struct Capsule
+ {
+ Vec3 pos = init::None;
+ Vec3 end = init::None;
+ float radius;
+ };
+
+ ///
+ struct Cone
+ {
+ Vec3 pos = init::None;
+ Vec3 end = init::None;
+ float radius;
+ };
+
+ ///
+ struct Cylinder
+ {
+ Vec3 pos = init::None;
+ Vec3 end = init::None;
+ float radius;
+ };
+
+ ///
+ struct Disk
+ {
+ Vec3 center = init::None;
+ Vec3 normal = init::None;
+ float radius;
+ };
+
+ ///
+ struct Obb
+ {
+ float mtx[16];
+ };
+
+ ///
+ struct Sphere
+ {
+ Vec3 center = init::None;
+ float radius;
+ };
+
+ ///
+ struct Triangle
+ {
+ Vec3 v0 = init::None;
+ Vec3 v1 = init::None;
+ Vec3 v2 = init::None;
+ };
+
+ ///
+ struct Ray
+ {
+ Vec3 pos = init::None;
+ Vec3 dir = init::None;
+ };
+
+ ///
+ struct Hit
+ {
+ Vec3 pos = init::None;
+ Plane plane = init::None;
+ };
+
+ ///
+ struct Interval
+ {
+ ///
+ Interval(float _val);
+
+ ///
+ Interval(float _min, float _max);
+
+ ///
+ void set(float _val);
+
+ ///
+ void setCenter(float _val);
+
+ ///
+ void expand(float _val);
+
+ float min;
+ float max;
+ };
+
+ ///
+ Vec3 getPointAt(const Ray& _ray, float _t);
+
+ ///
+ Vec3 getPointAt(const Line& _line, float _t);
+
+ ///
+ Vec3 getPointAt(const LineSegment& _line, float _t);
+
+ ///
+ Vec3 getCenter(const Aabb& _aabb);
+
+ ///
+ Vec3 getExtents(const Aabb& _aabb);
+
+ ///
+ Vec3 getCenter(const Triangle& _triangle);
+
+ ///
+ void toAabb(Aabb& _outAabb, const Vec3& _extents);
+
+ ///
+ void toAabb(Aabb& _outAabb, const Vec3& _center, const Vec3& _extents);
+
+ /// Convert cylinder to axis aligned bounding box.
+ void toAabb(Aabb& _outAabb, const Cylinder& _cylinder);
+
+ /// Convert disk to axis aligned bounding box.
+ void toAabb(Aabb& _outAabb, const Disk& _disk);
+
+ /// Convert oriented bounding box to axis aligned bounding box.
+ void toAabb(Aabb& _outAabb, const Obb& _obb);
+
+ /// Convert sphere to axis aligned bounding box.
+ void toAabb(Aabb& _outAabb, const Sphere& _sphere);
+
+ /// Convert triangle to axis aligned bounding box.
+ void toAabb(Aabb& _outAabb, const Triangle& _triangle);
+
+ /// Calculate axis aligned bounding box.
+ void toAabb(Aabb& _outAabb, const void* _vertices, uint32_t _numVertices, uint32_t _stride);
+
+ /// Transform vertices and calculate axis aligned bounding box.
+ void toAabb(Aabb& _outAabb, const float* _mtx, const void* _vertices, uint32_t _numVertices, uint32_t _stride);
+
+ /// Expand AABB.
+ void aabbExpand(Aabb& _outAabb, float _factor);
+
+ /// Expand AABB with xyz.
+ void aabbExpand(Aabb& _outAabb, const Vec3& _pos);
+
+ /// Calculate surface area of axis aligned bounding box.
+ float calcAreaAabb(const Aabb& _aabb);
+
+ /// Convert axis aligned bounding box to oriented bounding box.
+ void toObb(Obb& _outObb, const Aabb& _aabb);
+
+ /// Calculate oriented bounding box.
+ void calcObb(Obb& _outObb, const void* _vertices, uint32_t _numVertices, uint32_t _stride, uint32_t _steps = 17);
+
+ /// Calculate maximum bounding sphere.
+ void calcMaxBoundingSphere(Sphere& _outSphere, const void* _vertices, uint32_t _numVertices, uint32_t _stride);
+
+ /// Calculate minimum bounding sphere.
+ void calcMinBoundingSphere(Sphere& _outSphere, const void* _vertices, uint32_t _numVertices, uint32_t _stride, float _step = 0.01f);
+
+ /// Returns 6 (near, far, left, right, top, bottom) planes representing frustum planes.
+ void buildFrustumPlanes(Plane* _outPlanes, const float* _viewProj);
+
+ /// Returns point from 3 intersecting planes.
+ Vec3 intersectPlanes(const Plane& _pa, const Plane& _pb, const Plane& _pc);
+
+ /// Make screen space ray from x, y coordinate and inverse view-projection matrix.
+ Ray makeRay(float _x, float _y, const float* _invVp);
+
+ /// Intersect ray / AABB.
+ bool intersect(const Ray& _ray, const Aabb& _aabb, Hit* _hit = NULL);
+
+ /// Intersect ray / OBB.
+ bool intersect(const Ray& _ray, const Obb& _obb, Hit* _hit = NULL);
+
+ /// Intersect ray / cylinder.
+ bool intersect(const Ray& _ray, const Cylinder& _cylinder, Hit* _hit = NULL);
+
+ /// Intersect ray / capsule.
+ bool intersect(const Ray& _ray, const Capsule& _capsule, Hit* _hit = NULL);
+
+ /// Intersect ray / cone.
+ bool intersect(const Ray& _ray, const Cone& _cone, Hit* _hit = NULL);
+
+ /// Intersect ray / disk.
+ bool intersect(const Ray& _ray, const Disk& _disk, Hit* _hit = NULL);
+
+ /// Intersect ray / plane.
+ bool intersect(const Ray& _ray, const Plane& _plane, Hit* _hit = NULL);
+
+ /// Intersect ray / plane.
+ bool intersect(const Ray& _ray, const Plane& _plane, bool _doublesided, Hit* _hit = NULL);
+
+ /// Intersect ray / sphere.
+ bool intersect(const Ray& _ray, const Sphere& _sphere, Hit* _hit = NULL);
+
+ /// Intersect ray / triangle.
+ bool intersect(const Ray& _ray, const Triangle& _triangle, Hit* _hit = NULL);
+
+ ///
+ Vec3 closestPoint(const Line& _line, const Vec3& _point);
+
+ ///
+ Vec3 closestPoint(const LineSegment& _line, const Vec3& _point);
+
+ ///
+ Vec3 closestPoint(const Plane& _plane, const Vec3& _point);
+
+ ///
+ Vec3 closestPoint(const Aabb& _aabb, const Vec3& _point);
+
+ ///
+ Vec3 closestPoint(const Obb& _obb, const Vec3& _point);
+
+ ///
+ Vec3 closestPoint(const Triangle& _triangle, const Vec3& _point);
+
+ ///
+ bool overlap(const Interval& _interval, float _pos);
+
+ ///
+ bool overlap(const Interval& _intervalA, const Interval& _intervalB);
+
+ ///
+ bool overlap(const Aabb& _aabb, const Vec3& _pos);
+
+ ///
+ bool overlap(const Aabb& _aabb, const Sphere& _sphere);
+
+ ///
+ bool overlap(const Aabb& _aabbA, const Aabb& _aabbB);
+
+ ///
+ bool overlap(const Aabb& _aabb, const Plane& _plane);
+
+ ///
+ bool overlap(const Aabb& _aabb, const Triangle& _triangle);
+
+ ///
+ bool overlap(const Aabb& _aabb, const Cylinder& _cylinder);
+
+ ///
+ bool overlap(const Aabb& _aabb, const Capsule& _capsule);
+
+ ///
+ bool overlap(const Aabb& _aabb, const Cone& _cone);
+
+ ///
+ bool overlap(const Aabb& _aabb, const Disk& _disk);
+
+ ///
+ bool overlap(const Aabb& _aabb, const Obb& _obb);
+
+ ///
+ bool overlap(const Capsule& _capsule, const Vec3& _pos);
+
+ ///
+ bool overlap(const Capsule& _capsule, const Sphere& _sphere);
+
+ ///
+ bool overlap(const Capsule& _capsule, const Aabb& _aabb);
+
+ ///
+ bool overlap(const Capsule& _capsule, const Plane& _plane);
+
+ ///
+ bool overlap(const Capsule& _capsule, const Triangle& _triangle);
+
+ ///
+ bool overlap(const Capsule& _capsule, const Cylinder& _cylinder);
+
+ ///
+ bool overlap(const Capsule& _capsuleA, const Capsule& _capsuleB);
+
+ ///
+ bool overlap(const Capsule& _capsule, const Cone& _cone);
+
+ ///
+ bool overlap(const Capsule& _capsule, const Disk& _disk);
+
+ ///
+ bool overlap(const Capsule& _capsule, const Obb& _obb);
+
+ ///
+ bool overlap(const Cone& _cone, const Vec3& _pos);
+
+ ///
+ bool overlap(const Cone& _cone, const Sphere& _sphere);
+
+ ///
+ bool overlap(const Cone& _cone, const Aabb& _aabb);
+
+ ///
+ bool overlap(const Cone& _cone, const Plane& _plane);
+
+ ///
+ bool overlap(const Cone& _cone, const Triangle& _triangle);
+
+ ///
+ bool overlap(const Cone& _cone, const Cylinder& _cylinder);
+
+ ///
+ bool overlap(const Cone& _cone, const Capsule& _capsule);
+
+ ///
+ bool overlap(const Cone& _coneA, const Cone& _coneB);
+
+ ///
+ bool overlap(const Cone& _cone, const Disk& _disk);
+
+ ///
+ bool overlap(const Cone& _cone, const Obb& _obb);
+
+ ///
+ bool overlap(const Cylinder& _cylinder, const Vec3& _pos);
+
+ ///
+ bool overlap(const Cylinder& _cylinder, const Sphere& _sphere);
+
+ ///
+ bool overlap(const Cylinder& _cylinder, const Aabb& _aabb);
+
+ ///
+ bool overlap(const Cylinder& _cylinder, const Plane& _plane);
+
+ ///
+ bool overlap(const Cylinder& _cylinder, const Triangle& _triangle);
+
+ ///
+ bool overlap(const Cylinder& _cylinderA, const Cylinder& _cylinderB);
+
+ ///
+ bool overlap(const Cylinder& _cylinder, const Capsule& _capsule);
+
+ ///
+ bool overlap(const Cylinder& _cylinder, const Cone& _cone);
+
+ ///
+ bool overlap(const Cylinder& _cylinder, const Disk& _disk);
+
+ ///
+ bool overlap(const Cylinder& _cylinder, const Obb& _obb);
+
+ ///
+ bool overlap(const Disk& _disk, const Vec3& _pos);
+
+ ///
+ bool overlap(const Disk& _disk, const Sphere& _sphere);
+
+ ///
+ bool overlap(const Disk& _disk, const Aabb& _aabb);
+
+ ///
+ bool overlap(const Disk& _disk, const Plane& _plane);
+
+ ///
+ bool overlap(const Disk& _disk, const Triangle& _triangle);
+
+ ///
+ bool overlap(const Disk& _disk, const Cylinder& _cylinder);
+
+ ///
+ bool overlap(const Disk& _disk, const Capsule& _capsule);
+
+ ///
+ bool overlap(const Disk& _disk, const Cone& _cone);
+
+ ///
+ bool overlap(const Disk& _diskA, const Disk& _diskB);
+
+ ///
+ bool overlap(const Disk& _disk, const Obb& _obb);
+
+ ///
+ bool overlap(const Obb& _obb, const Vec3& _pos);
+
+ ///
+ bool overlap(const Obb& _obb, const Sphere& _sphere);
+
+ ///
+ bool overlap(const Obb& _obb, const Aabb& _aabb);
+
+ ///
+ bool overlap(const Obb& _obb, const Plane& _plane);
+
+ ///
+ bool overlap(const Obb& _obb, const Triangle& _triangle);
+
+ ///
+ bool overlap(const Obb& _obb, const Cylinder& _cylinder);
+
+ ///
+ bool overlap(const Obb& _obb, const Capsule& _capsule);
+
+ ///
+ bool overlap(const Obb& _obb, const Cone& _cone);
+
+ ///
+ bool overlap(const Obb& _obb, const Disk& _disk);
+
+ ///
+ bool overlap(const Obb& _obbA, const Obb& _obbB);
+
+ ///
+ bool overlap(const Plane& _plane, const Vec3& _pos);
+
+ ///
+ bool overlap(const Plane& _plane, const Sphere& _sphere);
+
+ ///
+ bool overlap(const Plane& _plane, const Aabb& _aabb);
+
+ ///
+ bool overlap(const Plane& _planeA, const Plane& _planeB);
+
+ ///
+ bool overlap(const Plane& _plane, const Triangle& _triangle);
+
+ ///
+ bool overlap(const Plane& _plane, const Cylinder& _cylinder);
+
+ ///
+ bool overlap(const Plane& _plane, const Capsule& _capsule);
+
+ ///
+ bool overlap(const Plane& _plane, const Cone& _cone);
+
+ ///
+ bool overlap(const Plane& _plane, const Disk& _disk);
+
+ ///
+ bool overlap(const Plane& _plane, const Obb& _obb);
+
+ ///
+ bool overlap(const Sphere& _sphere, const Vec3& _pos);
+
+ ///
+ bool overlap(const Sphere& _sphereA, const Sphere& _sphereB);
+
+ ///
+ bool overlap(const Sphere& _sphere, const Aabb& _aabb);
+
+ ///
+ bool overlap(const Sphere& _sphere, const Plane& _plane);
+
+ ///
+ bool overlap(const Sphere& _sphere, const Triangle& _triangle);
+
+ ///
+ bool overlap(const Sphere& _sphere, const Cylinder& _cylinder);
+
+ ///
+ bool overlap(const Sphere& _sphere, const Capsule& _capsule);
+
+ ///
+ bool overlap(const Sphere& _sphere, const Cone& _cone);
+
+ ///
+ bool overlap(const Sphere& _sphere, const Disk& _disk);
+
+ ///
+ bool overlap(const Sphere& _sphere, const Obb& _obb);
+
+ ///
+ bool overlap(const Triangle& _triangle, const Vec3& _pos);
+
+ ///
+ bool overlap(const Triangle& _triangle, const Sphere& _sphere);
+
+ ///
+ bool overlap(const Triangle& _triangle, const Aabb& _aabb);
+
+ ///
+ bool overlap(const Triangle& _triangle, const Plane& _plane);
+
+ ///
+ bool overlap(const Triangle& _triangleA, const Triangle& _triangleB);
+
+ ///
+ bool overlap(const Triangle& _triangle, const Cylinder& _cylinder);
+
+ ///
+ bool overlap(const Triangle& _triangle, const Capsule& _capsule);
+
+ ///
+ bool overlap(const Triangle& _triangle, const Cone& _cone);
+
+ ///
+ bool overlap(const Triangle& _triangle, const Disk& _disk);
+
+ ///
+ bool overlap(const Triangle& _triangle, const Obb& _obb);
+
+} // namespace bx
+
+#include "inline/bounds.inl"
+
+#endif // BX_BOUNDS_H_HEADER_GUARD
diff --git a/3rdparty/bx/include/bx/bx.h b/3rdparty/bx/include/bx/bx.h
index 7c2d06162aa..fb032a57fc6 100644
--- a/3rdparty/bx/include/bx/bx.h
+++ b/3rdparty/bx/include/bx/bx.h
@@ -1,6 +1,6 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_H_HEADER_GUARD
@@ -14,29 +14,61 @@
#include "platform.h"
#include "config.h"
+#include "constants.h"
#include "macros.h"
+#include "debug.h"
+#include "typetraits.h"
///
#define BX_COUNTOF(_x) sizeof(bx::CountOfRequireArrayArgumentT(_x) )
///
-#define BX_IGNORE_C4127(_x) bx::ignoreC4127(!!(_x) )
+#define BX_OFFSETOF(_type, _member) \
+ (reinterpret_cast<ptrdiff_t>(&(reinterpret_cast<_type*>(16)->_member) )-ptrdiff_t(16) )
///
-#define BX_ENABLED(_x) bx::isEnabled<!!(_x)>()
+#if BX_COMPILER_MSVC
+# define BX_IGNORE_C4127(_x) bx::ignoreC4127(!!(_x) )
+#else
+# define BX_IGNORE_C4127(_x) (!!(_x) )
+#endif // BX_COMPILER_MSVC
+
+///
+#define BX_ENABLED(_x) BX_IGNORE_C4127(bx::isEnabled<!!(_x)>::value)
namespace bx
{
- constexpr int32_t kExitSuccess = 0;
- constexpr int32_t kExitFailure = 1;
+ /// Arithmetic type `Ty` limits.
+ template<typename Ty, bool SignT = isSigned<Ty>()>
+ struct LimitsT;
+
+ /// Find the address of an object of a class that has an overloaded unary ampersand (&) operator.
+ template<typename Ty>
+ Ty* addressOf(Ty& _a);
+
+ /// Find the address of an object of a class that has an overloaded unary ampersand (&) operator.
+ template<typename Ty>
+ const Ty* addressOf(const Ty& _a);
- /// Template for avoiding MSVC: C4127: conditional expression is constant
- template<bool>
- constexpr bool isEnabled();
+ /// Returns typed pointer from typeless pointer offseted.
+ ///
+ /// @param[in] _ptr Pointer to get offset from.
+ /// @param[in] _offsetInBytes Offset from pointer in bytes.
+ ///
+ /// @returns Typed pointer from typeless pointer offseted.
+ ///
+ template<typename Ty>
+ Ty* addressOf(void* _ptr, ptrdiff_t _offsetInBytes = 0);
+ /// Returns typed pointer from typeless pointer offseted.
///
- template<class Ty>
- constexpr bool isTriviallyCopyable();
+ /// @param[in] _ptr Pointer to get offset from.
+ /// @param[in] _offsetInBytes Offset from pointer in bytes.
+ ///
+ /// @returns Typed pointer from typeless pointer offseted.
+ ///
+ template<typename Ty>
+ const Ty* addressOf(const void* _ptr, ptrdiff_t _offsetInBytes = 0);
/// Swap two values.
template<typename Ty>
@@ -45,55 +77,170 @@ namespace bx
/// Swap memory.
void swap(void* _a, void* _b, size_t _numBytes);
- /// Returns minimum of two values.
+ /// Returns numeric minimum of type.
template<typename Ty>
- constexpr Ty min(const Ty& _a, const Ty& _b);
+ constexpr Ty min();
- /// Returns maximum of two values.
+ /// Returns numeric maximum of type.
template<typename Ty>
- constexpr Ty max(const Ty& _a, const Ty& _b);
+ constexpr Ty max();
- /// Returns minimum of three values.
+ /// Returns minimum of two values.
template<typename Ty>
- constexpr Ty min(const Ty& _a, const Ty& _b, const Ty& _c);
+ constexpr Ty min(const Ty& _a, const TypeIdentityType<Ty>& _b);
- /// Returns maximum of three values.
+ /// Returns maximum of two values.
template<typename Ty>
- constexpr Ty max(const Ty& _a, const Ty& _b, const Ty& _c);
+ constexpr Ty max(const Ty& _a, const TypeIdentityType<Ty>& _b);
- /// Returns middle of three values.
- template<typename Ty>
- constexpr Ty mid(const Ty& _a, const Ty& _b, const Ty& _c);
+ /// Returns minimum of three or more values.
+ template<typename Ty, typename... Args>
+ constexpr Ty min(const Ty& _a, const TypeIdentityType<Ty>& _b, const Args&... _args);
+
+ /// Returns maximum of three or more values.
+ template<typename Ty, typename... Args>
+ constexpr Ty max(const Ty& _a, const TypeIdentityType<Ty>& _b, const Args&... _args);
+
+ /// Returns middle of three or more values.
+ template<typename Ty, typename... Args>
+ constexpr Ty mid(const Ty& _a, const TypeIdentityType<Ty>& _b, const Args&... _args);
/// Returns clamped value between min/max.
template<typename Ty>
- constexpr Ty clamp(const Ty& _a, const Ty& _min, const Ty& _max);
+ constexpr Ty clamp(const Ty& _a, const TypeIdentityType<Ty>& _min, const TypeIdentityType<Ty>& _max);
- /// Returns true if value is power of 2.
+ /// Returns true if value `_a` is power of 2.
template<typename Ty>
constexpr bool isPowerOf2(Ty _a);
+ /// Copy memory block.
+ ///
+ /// @param _dst Destination pointer.
+ /// @param _src Source pointer.
+ /// @param _numBytes Number of bytes to copy.
+ ///
+ /// @remark Source and destination memory blocks must not overlap.
///
void memCopy(void* _dst, const void* _src, size_t _numBytes);
+ /// Copy strided memory block.
///
- void memCopy(void* _dst, const void* _src, uint32_t _size, uint32_t _num, uint32_t _srcPitch, uint32_t _dstPitch);
-
+ /// @param _dst Destination pointer.
+ /// @param _dstStride Destination stride.
+ /// @param _src Source pointer.
+ /// @param _srcStride Source stride.
+ /// @param _stride Number of bytes per stride to copy.
+ /// @param _numStrides Number of strides.
///
- void gather(void* _dst, const void* _src, uint32_t _size, uint32_t _num, uint32_t _srcPitch);
-
+ /// @remark Source and destination memory blocks must not overlap.
///
- void scatter(void* _dst, const void* _src, uint32_t _size, uint32_t _num, uint32_t _dstPitch);
-
+ void memCopy(
+ void* _dst
+ , uint32_t _dstStride
+ , const void* _src
+ , uint32_t _srcStride
+ , uint32_t _stride
+ , uint32_t _numStrides
+ );
+
+ /// Copy memory block.
+ ///
+ /// @param _dst Destination pointer.
+ /// @param _src Source pointer.
+ /// @param _numBytes Number of bytes to copy.
+ ///
+ /// @remark If source and destination memory blocks overlap memory will be copied in reverse
+ /// order.
///
void memMove(void* _dst, const void* _src, size_t _numBytes);
+ /// Copy strided memory block.
+ ///
+ /// @param _dst Destination pointer.
+ /// @param _dstStride Destination stride.
+ /// @param _src Source pointer.
+ /// @param _srcStride Source stride.
+ /// @param _stride Number of bytes per stride to copy.
+ /// @param _numStrides Number of strides.
+ ///
+ /// @remark If source and destination memory blocks overlap memory will be copied in reverse
+ /// order.
+ ///
+ void memMove(
+ void* _dst
+ , uint32_t _dstStride
+ , const void* _src
+ , uint32_t _srcStride
+ , uint32_t _stride
+ , uint32_t _numStrides
+ );
+
+ /// Fill memory block to specified value `_ch`.
+ ///
+ /// @param _dst Destination pointer.
+ /// @param _ch Fill value.
+ /// @param _numBytes Number of bytes to copy.
///
void memSet(void* _dst, uint8_t _ch, size_t _numBytes);
+ /// Fill strided memory block to specified value `_ch`.
+ ///
+ /// @param _dst Destination pointer.
+ /// @param _dstStride Destination stride.
+ /// @param _ch Fill value.
+ /// @param _stride Number of bytes per stride to copy.
+ /// @param _numStrides Number of strides.
+ ///
+ void memSet(
+ void* _dst
+ , uint32_t _dstStride
+ , uint8_t _ch
+ , uint32_t _stride
+ , uint32_t _numStrides
+ );
+
+ /// Compare two memory blocks.
+ ///
+ /// @param _lhs Pointer to memory block.
+ /// @param _rhs Pointer to memory block.
+ /// @param _numBytes Number of bytes to compare.
+ ///
+ /// @returns 0 if two blocks are identical, positive value if first different byte in `_lhs` is
+ /// greater than corresponding byte in `_rhs`.
///
int32_t memCmp(const void* _lhs, const void* _rhs, size_t _numBytes);
+ /// Gather data scattered through memory into linear memory block.
+ ///
+ /// @param _dst Destination pointer.
+ /// @param _src Source pointer.
+ /// @param _stride Number of bytes per stride to copy.
+ /// @param _numStrides Number of strides.
+ ///
+ void gather(
+ void* _dst
+ , const void* _src
+ , uint32_t _srcStride
+ , uint32_t _stride
+ , uint32_t _numStrides
+ );
+
+ /// Scatter data from linear memory block through memory.
+ ///
+ /// @param _dst Destination pointer.
+ /// @param _dstStride Destination stride.
+ /// @param _src Source pointer.
+ /// @param _stride Number of bytes per stride to copy.
+ /// @param _numStrides Number of strides.
+ ///
+ void scatter(
+ void* _dst
+ , uint32_t _dstStride
+ , const void* _src
+ , uint32_t _stride
+ , uint32_t _numStrides
+ );
+
} // namespace bx
#include "inline/bx.inl"
diff --git a/3rdparty/bx/include/bx/commandline.h b/3rdparty/bx/include/bx/commandline.h
index dbd2af39427..10adb88cd58 100644
--- a/3rdparty/bx/include/bx/commandline.h
+++ b/3rdparty/bx/include/bx/commandline.h
@@ -1,6 +1,6 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_COMMANDLINE_H_HEADER_GUARD
diff --git a/3rdparty/bx/include/bx/config.h b/3rdparty/bx/include/bx/config.h
index 787859de6cf..4e32ccf23b3 100644
--- a/3rdparty/bx/include/bx/config.h
+++ b/3rdparty/bx/include/bx/config.h
@@ -1,16 +1,18 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_CONFIG_H_HEADER_GUARD
#define BX_CONFIG_H_HEADER_GUARD
-#include "bx.h"
+#ifndef BX_CONFIG_DEBUG
+# error "BX_CONFIG_DEBUG must be defined in build script!"
+#endif // BX_CONFIG_DEBUG
#ifndef BX_CONFIG_ALLOCATOR_DEBUG
-# define BX_CONFIG_ALLOCATOR_DEBUG 0
-#endif // BX_CONFIG_DEBUG_ALLOC
+# define BX_CONFIG_ALLOCATOR_DEBUG BX_CONFIG_DEBUG
+#endif // BX_CONFIG_ALLOCATOR_DEBUG
#ifndef BX_CONFIG_SUPPORTS_THREADING
# define BX_CONFIG_SUPPORTS_THREADING !(0 \
diff --git a/3rdparty/bx/include/bx/constants.h b/3rdparty/bx/include/bx/constants.h
new file mode 100644
index 00000000000..14c4cdbb35f
--- /dev/null
+++ b/3rdparty/bx/include/bx/constants.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2011-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
+ */
+
+#ifndef BX_CONSTANTS_H_HEADER_GUARD
+#define BX_CONSTANTS_H_HEADER_GUARD
+
+namespace bx
+{
+ /// Used to return successful execution of a program code.
+ constexpr int32_t kExitSuccess = 0;
+
+ /// Used to return unsuccessful execution of a program code.
+ constexpr int32_t kExitFailure = 1;
+
+ /// The ratio of a circle's circumference to its diameter,
+ constexpr float kPi = 3.1415926535897932384626433832795f;
+
+ /// The ratio of a circle's circumference to its radius. Pi multiplied by 2, or Tau. pi*2
+ constexpr float kPi2 = 6.2831853071795864769252867665590f;
+
+ /// The reciprocal of pi. 1/pi
+ constexpr float kInvPi = 1.0f/kPi;
+
+ /// Pi divided by two. pi/2
+ constexpr float kPiHalf = 1.5707963267948966192313216916398f;
+
+ /// Pi divided by four. pi/4
+ constexpr float kPiQuarter = 0.7853981633974483096156608458199f;
+
+ /// The square root of two. sqrt(2)
+ constexpr float kSqrt2 = 1.4142135623730950488016887242097f;
+
+ /// ln(10)
+ constexpr float kLogNat10 = 2.3025850929940456840179914546844f;
+
+ /// The logarithm of the e to base 2. ln(kE) / ln(2)
+ constexpr float kInvLogNat2 = 1.4426950408889634073599246810019f;
+
+ /// The natural logarithm of the 2. ln(2)
+ constexpr float kLogNat2Hi = 0.6931471805599453094172321214582f;
+
+ ///
+ constexpr float kLogNat2Lo = 1.90821492927058770002e-10f;
+
+ /// The base of natural logarithms. e(1)
+ constexpr float kE = 2.7182818284590452353602874713527f;
+
+ ///
+ constexpr float kNearZero = 1.0f/float(1 << 28);
+
+ /// Smallest normalized positive floating-point number.
+ constexpr float kFloatSmallest = 1.175494351e-38f;
+
+ /// Maximum representable floating-point number.
+ constexpr float kFloatLargest = 3.402823466e+38f;
+
+ /// Smallest normalized positive double-precision floating-point number.
+ constexpr double kDoubleSmallest = 2.2250738585072014e-308;
+
+ /// Largest representable double-precision floating-point number.
+ constexpr double kDoubleLargest = 1.7976931348623158e+308;
+
+ ///
+ extern const float kInfinity;
+
+} // namespace bx
+
+#endif // BX_CONSTANTS_H_HEADER_GUARD
diff --git a/3rdparty/bx/include/bx/cpu.h b/3rdparty/bx/include/bx/cpu.h
index a2e81a1a1ca..dc3a544bca0 100644
--- a/3rdparty/bx/include/bx/cpu.h
+++ b/3rdparty/bx/include/bx/cpu.h
@@ -1,6 +1,6 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_CPU_H_HEADER_GUARD
diff --git a/3rdparty/bx/include/bx/debug.h b/3rdparty/bx/include/bx/debug.h
index 80efaf97c87..3a0719c32ee 100644
--- a/3rdparty/bx/include/bx/debug.h
+++ b/3rdparty/bx/include/bx/debug.h
@@ -1,15 +1,17 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_DEBUG_H_HEADER_GUARD
#define BX_DEBUG_H_HEADER_GUARD
-#include "string.h"
+#include "bx.h"
namespace bx
{
+ class StringView;
+
///
void debugBreak();
diff --git a/3rdparty/bx/include/bx/easing.h b/3rdparty/bx/include/bx/easing.h
index 8581b975c9c..05ee40e788c 100644
--- a/3rdparty/bx/include/bx/easing.h
+++ b/3rdparty/bx/include/bx/easing.h
@@ -1,6 +1,6 @@
/*
- * Copyright 2011-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2011-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_EASING_H_HEADER_GUARD
diff --git a/3rdparty/bx/include/bx/endian.h b/3rdparty/bx/include/bx/endian.h
index 22965b5f31a..559e4bab453 100644
--- a/3rdparty/bx/include/bx/endian.h
+++ b/3rdparty/bx/include/bx/endian.h
@@ -1,6 +1,6 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_ENDIAN_H_HEADER_GUARD
@@ -28,13 +28,13 @@ namespace bx
///
uint64_t endianSwap(uint64_t _in);
- /// Input argument is encoded as little endian, convert it if neccessary
- /// depending on host CPU endianess.
+ /// Input argument is encoded as little endian, convert it if necessary
+ /// depending on host CPU endianness.
template <typename Ty>
Ty toLittleEndian(const Ty _in);
- /// Input argument is encoded as big endian, convert it if neccessary
- /// depending on host CPU endianess.
+ /// Input argument is encoded as big endian, convert it if necessary
+ /// depending on host CPU endianness.
template <typename Ty>
Ty toBigEndian(const Ty _in);
diff --git a/3rdparty/bx/include/bx/error.h b/3rdparty/bx/include/bx/error.h
index 1eb220e7be0..a44a3a8d8cb 100644
--- a/3rdparty/bx/include/bx/error.h
+++ b/3rdparty/bx/include/bx/error.h
@@ -1,6 +1,6 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_ERROR_H_HEADER_GUARD
@@ -8,22 +8,22 @@
#include "string.h"
-#define BX_ERROR_SET(_ptr, _result, _msg) \
- BX_MACRO_BLOCK_BEGIN \
- (_ptr)->setError(_result, "" _msg); \
- BX_MACRO_BLOCK_END
+#define BX_ERROR_SET(_ptr, _result, _msg) \
+ BX_MACRO_BLOCK_BEGIN \
+ (_ptr)->setError(_result, "" _msg); \
+ BX_MACRO_BLOCK_END
-#define BX_ERROR_USE_TEMP_WHEN_NULL(_ptr) \
- const bx::Error tmpError; /* It should not be used directly! */ \
- _ptr = NULL == _ptr ? const_cast<bx::Error*>(&tmpError) : _ptr
+#define BX_ERROR_USE_TEMP_WHEN_NULL(_ptr) \
+ const bx::Error tmpError; /* It should not be used directly! */ \
+ _ptr = NULL == _ptr ? const_cast<bx::Error*>(&tmpError) : _ptr
-#define BX_ERROR_SCOPE(_ptr) \
- BX_ERROR_USE_TEMP_WHEN_NULL(_ptr); \
- bx::ErrorScope bxErrorScope(const_cast<bx::Error*>(&tmpError) )
+#define BX_ERROR_SCOPE(_ptr, ...) \
+ BX_ERROR_USE_TEMP_WHEN_NULL(_ptr); \
+ bx::ErrorScope bxErrorScope(const_cast<bx::Error*>(&tmpError), "" __VA_ARGS__)
-#define BX_ERROR_RESULT(_err, _code) \
- BX_STATIC_ASSERT(_code != 0, "ErrorCode 0 is reserved!"); \
- static const bx::ErrorResult _err = { _code }
+#define BX_ERROR_RESULT(_err, _code) \
+ BX_STATIC_ASSERT(_code != 0, "ErrorCode 0 is reserved!"); \
+ static constexpr bx::ErrorResult _err = { _code }
namespace bx
{
@@ -38,7 +38,6 @@ namespace bx
{
BX_CLASS(Error
, NO_COPY
- , NO_ASSIGNMENT
);
public:
@@ -71,23 +70,57 @@ namespace bx
uint32_t m_code;
};
+ /// Do nothing even if error is set.
+ class ErrorIgnore : public Error
+ {
+ public:
+ ///
+ operator Error*();
+ };
+
+ /// In debug build assert if error is set.
+ class ErrorAssert : public Error
+ {
+ public:
+ ///
+ ~ErrorAssert();
+
+ ///
+ operator Error*();
+ };
+
+ /// Exit application if error is set.
+ class ErrorFatal : public Error
+ {
+ public:
+ ///
+ ~ErrorFatal();
+
+ ///
+ operator Error*();
+ };
+
///
class ErrorScope
{
BX_CLASS(ErrorScope
+ , NO_DEFAULT_CTOR
, NO_COPY
- , NO_ASSIGNMENT
);
public:
///
- ErrorScope(Error* _err);
+ ErrorScope(Error* _err, const StringView& _name);
///
~ErrorScope();
+ ///
+ const StringView& getName() const;
+
private:
Error* m_err;
+ const StringView m_name;
};
} // namespace bx
diff --git a/3rdparty/bx/include/bx/file.h b/3rdparty/bx/include/bx/file.h
index 4c0dd415f1b..88def0e0054 100644
--- a/3rdparty/bx/include/bx/file.h
+++ b/3rdparty/bx/include/bx/file.h
@@ -1,6 +1,6 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_FILE_H_HEADER_GUARD
@@ -11,19 +11,19 @@
namespace bx
{
- ///
+ /// Returns standard input reader.
ReaderI* getStdIn();
- ///
+ /// Returns standard output writer.
WriterI* getStdOut();
- ///
+ /// Returns standard error writer.
WriterI* getStdErr();
- ///
+ /// Returns null output writer.
WriterI* getNullOut();
- ///
+ /// File reader.
class FileReader : public FileReaderI
{
public:
@@ -49,7 +49,7 @@ namespace bx
BX_ALIGN_DECL(16, uint8_t) m_internal[64];
};
- ///
+ /// File writer.
class FileWriter : public FileWriterI
{
public:
@@ -75,23 +75,68 @@ namespace bx
BX_ALIGN_DECL(16, uint8_t) m_internal[64];
};
- ///
- struct FileInfo
+ /// File type.
+ struct FileType
{
+ /// File types:
enum Enum
{
- Regular,
- Directory,
+ File, //!< File.
+ Dir, //!< Directory.
Count
};
+ };
+
+ /// File info.
+ struct FileInfo
+ {
+ FilePath filePath; //!< File path.
+ uint64_t size; //!< File size.
+ FileType::Enum type; //!< File type.
+ };
+
+ /// Directory reader.
+ class DirectoryReader : public ReaderOpenI, public CloserI, public ReaderI
+ {
+ public:
+ ///
+ DirectoryReader();
+
+ ///
+ virtual ~DirectoryReader();
+
+ ///
+ virtual bool open(const FilePath& _filePath, Error* _err) override;
+
+ ///
+ virtual void close() override;
+
+ ///
+ virtual int32_t read(void* _data, int32_t _size, Error* _err) override;
- uint64_t m_size;
- Enum m_type;
+ private:
+ BX_ALIGN_DECL(16, uint8_t) m_internal[sizeof(FilePath)+sizeof(FileInfo)+16];
};
+ /// FIle stat.
+ bool stat(FileInfo& _outFileInfo, const FilePath& _filePath);
+
+ /// Creates a directory named `_filePath`.
+ ///
+ bool make(const FilePath& _filePath, Error* _err = bx::ErrorIgnore{});
+
+ /// Creates a directory named `_filePath` along with all necessary parents.
+ ///
+ bool makeAll(const FilePath& _filePath, Error* _err = bx::ErrorIgnore{});
+
+ /// Removes file or directory.
+ ///
+ bool remove(const FilePath& _filePath, Error* _err = bx::ErrorIgnore{});
+
+ /// Removes file or directory recursively.
///
- bool stat(const FilePath& _filePath, FileInfo& _outFileInfo);
+ bool removeAll(const FilePath& _filePath, Error* _err = bx::ErrorIgnore{});
} // namespace bx
diff --git a/3rdparty/bx/include/bx/filepath.h b/3rdparty/bx/include/bx/filepath.h
index c71a1695cfb..464799e2166 100644
--- a/3rdparty/bx/include/bx/filepath.h
+++ b/3rdparty/bx/include/bx/filepath.h
@@ -1,6 +1,6 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_FILEPATH_H_HEADER_GUARD
@@ -9,11 +9,11 @@
#include "error.h"
#include "string.h"
-BX_ERROR_RESULT(BX_ERROR_ACCESS, BX_MAKEFOURCC('b', 'x', 0, 0) );
-BX_ERROR_RESULT(BX_ERROR_NOT_DIRECTORY, BX_MAKEFOURCC('b', 'x', 0, 1) );
-
namespace bx
{
+ BX_ERROR_RESULT(kErrorAccess, BX_MAKEFOURCC('b', 'x', 1, 1) );
+ BX_ERROR_RESULT(kErrorNotDirectory, BX_MAKEFOURCC('b', 'x', 1, 2) );
+
constexpr int32_t kMaxFilePath = 1024;
/// Special predefined OS directories.
@@ -79,9 +79,13 @@ namespace bx
///
void join(const StringView& _str);
- /// Returns C string to file path.
+ /// Implicitly converts FilePath to StringView.
+ ///
+ operator StringView() const;
+
+ /// Returns zero-terminated C string pointer to file path.
///
- const char* get() const;
+ const char* getCPtr() const;
/// If path is `/abv/gd/555/333/pod.mac` returns `/abv/gd/555/333/`.
///
@@ -111,22 +115,6 @@ namespace bx
char m_filePath[kMaxFilePath];
};
- /// Creates a directory named `_filePath`.
- ///
- bool make(const FilePath& _filePath, Error* _err = NULL);
-
- /// Creates a directory named `_filePath` along with all necessary parents.
- ///
- bool makeAll(const FilePath& _filePath, Error* _err = NULL);
-
- /// Removes file or directory.
- ///
- bool remove(const FilePath& _filePath, Error* _err = NULL);
-
- /// Removes file or directory recursivelly.
- ///
- bool removeAll(const FilePath& _filePath, Error* _err = NULL);
-
} // namespace bx
#endif // BX_FILEPATH_H_HEADER_GUARD
diff --git a/3rdparty/bx/include/bx/float4x4_t.h b/3rdparty/bx/include/bx/float4x4_t.h
index 3250d929db3..54bc492aece 100644
--- a/3rdparty/bx/include/bx/float4x4_t.h
+++ b/3rdparty/bx/include/bx/float4x4_t.h
@@ -1,6 +1,6 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_FLOAT4X4_H_HEADER_GUARD
@@ -10,25 +10,35 @@
namespace bx
{
- ///
+ /// 4x4 matrix.
BX_ALIGN_DECL_16(struct) float4x4_t
{
simd128_t col[4];
};
- ///
+ /// Multiplies vector `_a` with matrix `_b` ignoring W component of vector `_a`.
simd128_t simd_mul_xyz1(simd128_t _a, const float4x4_t* _b);
- ///
+ /// Multiplies vector `_a` with matrix `_b`.
simd128_t simd_mul(simd128_t _a, const float4x4_t* _b);
- ///
+ /// Multiplies two matrices.
void float4x4_mul(float4x4_t* _result, const float4x4_t* _a, const float4x4_t* _b);
- ///
+ /// Multiplies two 3x4 affine matrices (i.e. "model" or "world" matrices).
+ /// This function is a micro-optimized version of float4x4_mul() in the case
+ /// when the last row of the both input matrices are (0, 0, 0, 1).
+ void model4x4_mul(float4x4_t* _result, const float4x4_t* _a, const float4x4_t* _b);
+
+ /// Multiplies a 3x4 affine matrix with a general 4x4 matrix.
+ /// This function is a micro-optimized version of float4x4_mul() in the case
+ /// when the last row of the _model input matrix is (0, 0, 0, 1).
+ void model4x4_mul_viewproj4x4(float4x4_t* _result, const float4x4_t* _model, const float4x4_t* _viewProj);
+
+ /// Transpose of matrix.
void float4x4_transpose(float4x4_t* _result, const float4x4_t* _mtx);
- ///
+ /// Inverse of matrix.
void float4x4_inverse(float4x4_t* _result, const float4x4_t* _a);
} // namespace bx
diff --git a/3rdparty/bx/include/bx/handlealloc.h b/3rdparty/bx/include/bx/handlealloc.h
index 21b07ccca63..f7335e452ca 100644
--- a/3rdparty/bx/include/bx/handlealloc.h
+++ b/3rdparty/bx/include/bx/handlealloc.h
@@ -1,6 +1,6 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_HANDLE_ALLOC_H_HEADER_GUARD
@@ -12,7 +12,7 @@
namespace bx
{
- static const uint16_t kInvalidHandle = UINT16_MAX;
+ constexpr uint16_t kInvalidHandle = UINT16_MAX;
///
class HandleAlloc
diff --git a/3rdparty/bx/include/bx/hash.h b/3rdparty/bx/include/bx/hash.h
index 9ced6947c9f..cb6fe18764f 100644
--- a/3rdparty/bx/include/bx/hash.h
+++ b/3rdparty/bx/include/bx/hash.h
@@ -1,6 +1,6 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_HASH_H_HEADER_GUARD
@@ -11,95 +11,99 @@
namespace bx
{
- /// MurmurHash2 was written by Austin Appleby, and is placed in the public
- /// domain. The author hereby disclaims copyright to this source code.
- ///
- class HashMurmur2A
+ /// 32-bit Adler checksum hash.
+ class HashAdler32
{
public:
///
- void begin(uint32_t _seed = 0);
+ void begin();
+
+ ///
+ void add(const void* _data, int32_t _len);
+
+ ///
+ void add(const char* _data);
///
- void add(const void* _data, int _len);
+ void add(const StringView& _data);
///
template<typename Ty>
- void add(Ty _value);
+ void add(const Ty& _data);
///
uint32_t end();
private:
- ///
- void addAligned(const void* _data, int _len);
+ uint32_t m_a;
+ uint32_t m_b;
+ };
- ///
- void addUnaligned(const void* _data, int _len);
+ /// 32-bit cyclic redundancy checksum hash.
+ class HashCrc32
+ {
+ public:
+ enum Enum
+ {
+ Ieee, //!< 0xedb88320
+ Castagnoli, //!< 0x82f63b78
+ Koopman, //!< 0xeb31d82e
- ///
- static void readUnaligned(const void* _data, uint32_t& _out);
+ Count
+ };
///
- void mixTail(const uint8_t*& _data, int& _len);
+ void begin(Enum _type = Ieee);
- uint32_t m_hash;
- uint32_t m_tail;
- uint32_t m_count;
- uint32_t m_size;
- };
+ ///
+ void add(const void* _data, int32_t _len);
- ///
- class HashAdler32
- {
- public:
///
- void begin();
+ void add(const char* _data);
///
- void add(const void* _data, int _len);
+ void add(const StringView& _data);
///
template<typename Ty>
- void add(Ty _value);
+ void add(const Ty& _data);
///
uint32_t end();
private:
- uint32_t m_a;
- uint32_t m_b;
+ const uint32_t* m_table;
+ uint32_t m_hash;
};
- ///
- class HashCrc32
+ /// 32-bit multiply and rotate hash.
+ class HashMurmur2A
{
public:
- enum Enum
- {
- Ieee, //!< 0xedb88320
- Castagnoli, //!< 0x82f63b78
- Koopman, //!< 0xeb31d82e
+ ///
+ void begin(uint32_t _seed = 0);
- Count
- };
+ ///
+ void add(const void* _data, int32_t _len);
///
- void begin(Enum _type = Ieee);
+ void add(const char* _data);
///
- void add(const void* _data, int _len);
+ void add(const StringView& _data);
///
template<typename Ty>
- void add(Ty _value);
+ void add(const Ty& _data);
///
uint32_t end();
private:
- const uint32_t* m_table;
uint32_t m_hash;
+ uint32_t m_tail;
+ uint32_t m_count;
+ uint32_t m_size;
};
///
@@ -107,16 +111,16 @@ namespace bx
uint32_t hash(const void* _data, uint32_t _size);
///
- template<typename HashT, typename Ty>
- uint32_t hash(const Ty& _data);
+ template<typename HashT>
+ uint32_t hash(const char* _data);
///
template<typename HashT>
uint32_t hash(const StringView& _data);
///
- template<typename HashT>
- uint32_t hash(const char* _data);
+ template<typename HashT, typename Ty>
+ uint32_t hash(const Ty& _data);
} // namespace bx
diff --git a/3rdparty/bx/include/bx/inline/allocator.inl b/3rdparty/bx/include/bx/inline/allocator.inl
index 1ff5f647345..82788d1fedd 100644
--- a/3rdparty/bx/include/bx/inline/allocator.inl
+++ b/3rdparty/bx/include/bx/inline/allocator.inl
@@ -1,6 +1,6 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_ALLOCATOR_H_HEADER_GUARD
@@ -22,20 +22,12 @@ namespace bx
{
}
- 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);
+ uintptr_t aligned = bx::alignUp(unaligned, int32_t(_align) );
un.addr = aligned;
return un.ptr;
}
@@ -57,7 +49,7 @@ namespace bx
inline void* alignedAlloc(AllocatorI* _allocator, size_t _size, size_t _align, const char* _file, uint32_t _line)
{
- const size_t align = max(_align, sizeof(uint32_t) );;
+ const size_t align = max(_align, sizeof(uint32_t) );
const 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);
diff --git a/3rdparty/bx/include/bx/inline/bounds.inl b/3rdparty/bx/include/bx/inline/bounds.inl
new file mode 100644
index 00000000000..1ecc59a8f18
--- /dev/null
+++ b/3rdparty/bx/include/bx/inline/bounds.inl
@@ -0,0 +1,257 @@
+/*
+ * Copyright 2011-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
+ */
+
+#ifndef BX_BOUNDS_H_HEADER_GUARD
+# error "Must be included from bounds.h!"
+#endif // BX_BOUNDS_H_HEADER_GUARD
+
+namespace bx
+{
+ inline Interval::Interval(float _val)
+ : min(_val)
+ , max(_val)
+ {
+ }
+
+ inline Interval::Interval(float _min, float _max)
+ : min(_min)
+ , max(_max)
+ {
+ }
+
+ inline void Interval::set(float _val)
+ {
+ min = _val;
+ max = _val;
+ }
+
+ inline void Interval::setCenter(float _val)
+ {
+ const float extents = (max - min) * 0.5f;
+ min = _val - extents;
+ max = _val + extents;
+ }
+
+ inline void Interval::expand(float _val)
+ {
+ min = bx::min(min, _val);
+ max = bx::max(max, _val);
+ }
+
+ inline Vec3 getPointAt(const Ray& _ray, float _t)
+ {
+ return mad(_ray.dir, _t, _ray.pos);
+ }
+
+ inline Vec3 getPointAt(const Line& _line, float _t)
+ {
+ return mad(_line.dir, _t, _line.pos);
+ }
+
+ inline Vec3 getPointAt(const LineSegment& _line, float _t)
+ {
+ return lerp(_line.pos, _line.end, _t);
+ }
+
+ inline bool intersect(const Ray& _ray, const Plane& _plane, Hit* _hit)
+ {
+ return intersect(_ray, _plane, false, _hit);
+ }
+
+ inline bool overlap(const Interval& _interval, float _t)
+ {
+ return _t > _interval.min
+ && _t < _interval.max
+ ;
+ }
+
+ inline bool overlap(const Interval& _intervalA, const Interval& _intervalB)
+ {
+ return _intervalA.max > _intervalB.min
+ && _intervalB.max > _intervalA.min
+ ;
+ }
+
+ inline bool overlap(const Aabb& _aabb, const Sphere& _sphere)
+ {
+ return overlap(_sphere, _aabb);
+ }
+
+ inline bool overlap(const Aabb& _aabb, const Cylinder& _cylinder)
+ {
+ return overlap(_cylinder, _aabb);
+ }
+
+ inline bool overlap(const Capsule& _capsule, const Sphere& _sphere)
+ {
+ return overlap(_sphere, _capsule);
+ }
+
+ inline bool overlap(const Capsule& _capsule, const Aabb& _aabb)
+ {
+ return overlap(_aabb, _capsule);
+ }
+
+ inline bool overlap(const Capsule& _capsule, const Triangle& _triangle)
+ {
+ return overlap(_triangle, _capsule);
+ }
+
+ inline bool overlap(const Capsule& _capsule, const Cone& _cone)
+ {
+ return overlap(_cone, _capsule);
+ }
+
+ inline bool overlap(const Capsule& _capsule, const Cylinder& _cylinder)
+ {
+ return overlap(_cylinder, _capsule);
+ }
+
+ inline bool overlap(const Capsule& _capsule, const Disk& _disk)
+ {
+ return overlap(_disk, _capsule);
+ }
+
+ inline bool overlap(const Capsule& _capsule, const Obb& _obb)
+ {
+ return overlap(_obb, _capsule);
+ }
+
+ inline bool overlap(const Cone& _cone, const Sphere& _sphere)
+ {
+ return overlap(_sphere, _cone);
+ }
+
+ inline bool overlap(const Cone& _cone, const Aabb& _aabb)
+ {
+ return overlap(_aabb, _cone);
+ }
+
+ inline bool overlap(const Cone& _cone, const Plane& _plane)
+ {
+ return overlap(_plane, _cone);
+ }
+
+ inline bool overlap(const Cone& _cone, const Triangle& _triangle)
+ {
+ return overlap(_triangle, _cone);
+ }
+
+ inline bool overlap(const Cylinder& _cylinder, const Triangle& _triangle)
+ {
+ return overlap(_triangle, _cylinder);
+ }
+
+ inline bool overlap(const Cylinder& _cylinder, const Cone& _cone)
+ {
+ return overlap(_cone, _cylinder);
+ }
+
+ inline bool overlap(const Disk& _disk, const Sphere& _sphere)
+ {
+ return overlap(_sphere, _disk);
+ }
+
+ inline bool overlap(const Disk& _disk, const Aabb& _aabb)
+ {
+ return overlap(_aabb, _disk);
+ }
+
+ inline bool overlap(const Disk& _disk, const Triangle& _triangle)
+ {
+ return overlap(_triangle, _disk);
+ }
+
+ inline bool overlap(const Disk& _disk, const Cylinder& _cylinder)
+ {
+ return overlap(_cylinder, _disk);
+ }
+
+ inline bool overlap(const Disk& _disk, const Cone& _cone)
+ {
+ return overlap(_cone, _disk);
+ }
+
+ inline bool overlap(const Obb& _obb, const Sphere& _sphere)
+ {
+ return overlap(_sphere, _obb);
+ }
+
+ inline bool overlap(const Obb& _obb, const Aabb& _aabb)
+ {
+ return overlap(_aabb, _obb);
+ }
+
+ inline bool overlap(const Obb& _obb, const Triangle& _triangle)
+ {
+ return overlap(_triangle, _obb);
+ }
+
+ inline bool overlap(const Obb& _obb, const Cylinder& _cylinder)
+ {
+ return overlap(_cylinder, _obb);
+ }
+
+ inline bool overlap(const Obb& _obb, const Cone& _cone)
+ {
+ return overlap(_cone, _obb);
+ }
+
+ inline bool overlap(const Obb& _obb, const Disk& _disk)
+ {
+ return overlap(_disk, _obb);
+ }
+
+ inline bool overlap(const Plane& _plane, const Sphere& _sphere)
+ {
+ return overlap(_sphere, _plane);
+ }
+
+ inline bool overlap(const Plane& _plane, const Aabb& _aabb)
+ {
+ return overlap(_aabb, _plane);
+ }
+
+ inline bool overlap(const Plane& _plane, const Triangle& _triangle)
+ {
+ return overlap(_triangle, _plane);
+ }
+
+ inline bool overlap(const Plane& _plane, const Cylinder& _cylinder)
+ {
+ return overlap(_cylinder, _plane);
+ }
+
+ inline bool overlap(const Plane& _plane, const Capsule& _capsule)
+ {
+ return overlap(_capsule, _plane);
+ }
+
+ inline bool overlap(const Plane& _plane, const Disk& _disk)
+ {
+ return overlap(_disk, _plane);
+ }
+
+ inline bool overlap(const Plane& _plane, const Obb& _obb)
+ {
+ return overlap(_obb, _plane);
+ }
+
+ inline bool overlap(const Sphere& _sphere, const Cylinder& _cylinder)
+ {
+ return overlap(_cylinder, _sphere);
+ }
+
+ inline bool overlap(const Triangle& _triangle, const Sphere& _sphere)
+ {
+ return overlap(_sphere, _triangle);
+ }
+
+ inline bool overlap(const Triangle& _triangle, const Aabb& _aabb)
+ {
+ return overlap(_aabb, _triangle);
+ }
+
+} // namespace bx
diff --git a/3rdparty/bx/include/bx/inline/bx.inl b/3rdparty/bx/include/bx/inline/bx.inl
index c17649a5d69..3c651854281 100644
--- a/3rdparty/bx/include/bx/inline/bx.inl
+++ b/3rdparty/bx/include/bx/inline/bx.inl
@@ -1,6 +1,6 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_H_HEADER_GUARD
@@ -12,70 +12,131 @@ namespace bx
// Reference(S):
// - https://web.archive.org/web/20181115035420/http://cnicholson.net/2011/01/stupid-c-tricks-a-better-sizeof_array/
//
- template<typename Ty, size_t Num>
- char(&CountOfRequireArrayArgumentT(const Ty(&)[Num]))[Num];
+ template<typename Ty, size_t NumT>
+ char (&CountOfRequireArrayArgumentT(const Ty (&)[NumT]) )[NumT];
- template<bool>
- inline constexpr bool isEnabled()
+ template<bool B>
+ struct isEnabled
{
- return true;
+ // Template for avoiding MSVC: C4127: conditional expression is constant
+ static constexpr bool value = B;
+ };
+
+ inline constexpr bool ignoreC4127(bool _x)
+ {
+ return _x;
}
- template<class Ty>
- inline constexpr bool isTriviallyCopyable()
+ template<typename Ty>
+ inline Ty* addressOf(Ty& _a)
{
- return __is_trivially_copyable(Ty);
+ return reinterpret_cast<Ty*>(
+ &const_cast<char&>(
+ reinterpret_cast<const volatile char&>(_a)
+ )
+ );
}
- template<>
- inline constexpr bool isEnabled<false>()
+ template<typename Ty>
+ inline const Ty* addressOf(const Ty& _a)
{
- return false;
+ return reinterpret_cast<const Ty*>(
+ &const_cast<char&>(
+ reinterpret_cast<const volatile char&>(_a)
+ )
+ );
}
- inline constexpr bool ignoreC4127(bool _x)
+ template<typename Ty>
+ inline Ty* addressOf(void* _ptr, ptrdiff_t _offsetInBytes)
{
- return _x;
+ return (Ty*)( (uint8_t*)_ptr + _offsetInBytes);
}
template<typename Ty>
- inline void swap(Ty& _a, Ty& _b)
+ inline const Ty* addressOf(const void* _ptr, ptrdiff_t _offsetInBytes)
{
- Ty tmp = _a; _a = _b; _b = tmp;
+ return (const Ty*)( (const uint8_t*)_ptr + _offsetInBytes);
}
template<typename Ty>
- inline constexpr Ty min(const Ty& _a, const Ty& _b)
+ inline void swap(Ty& _a, Ty& _b)
{
- return _a < _b ? _a : _b;
+ Ty tmp = move(_a); _a = move(_b); _b = move(tmp);
}
template<typename Ty>
- inline constexpr Ty max(const Ty& _a, const Ty& _b)
+ struct LimitsT<Ty, true>
{
- return _a > _b ? _a : _b;
+ static constexpr Ty max = ( ( (Ty(1) << ( (sizeof(Ty) * 8) - 2) ) - Ty(1) ) << 1) | Ty(1);
+ static constexpr Ty min = -max - Ty(1);
+ };
+
+ template<typename Ty>
+ struct LimitsT<Ty, false>
+ {
+ static constexpr Ty min = 0;
+ static constexpr Ty max = Ty(-1);
+ };
+
+ template<>
+ struct LimitsT<float, true>
+ {
+ static constexpr float min = -kFloatLargest;
+ static constexpr float max = kFloatLargest;
+ };
+
+ template<>
+ struct LimitsT<double, true>
+ {
+ static constexpr double min = -kDoubleLargest;
+ static constexpr double max = kDoubleLargest;
+ };
+
+ template<typename Ty>
+ inline constexpr Ty max()
+ {
+ return bx::LimitsT<Ty>::max;
}
template<typename Ty>
- inline constexpr Ty min(const Ty& _a, const Ty& _b, const Ty& _c)
+ inline constexpr Ty min()
{
- return min(min(_a, _b), _c);
+ return bx::LimitsT<Ty>::min;
}
template<typename Ty>
- inline constexpr Ty max(const Ty& _a, const Ty& _b, const Ty& _c)
+ inline constexpr Ty min(const Ty& _a, const TypeIdentityType<Ty>& _b)
{
- return max(max(_a, _b), _c);
+ return _a < _b ? _a : _b;
}
template<typename Ty>
- inline constexpr Ty mid(const Ty& _a, const Ty& _b, const Ty& _c)
+ inline constexpr Ty max(const Ty& _a, const TypeIdentityType<Ty>& _b)
+ {
+ return _a > _b ? _a : _b;
+ }
+
+ template<typename Ty, typename... Args>
+ inline constexpr Ty min(const Ty& _a, const TypeIdentityType<Ty>& _b, const Args&... _args)
+ {
+ return min(min(_a, _b), _args...);
+ }
+
+ template<typename Ty, typename... Args>
+ inline constexpr Ty max(const Ty& _a, const TypeIdentityType<Ty>& _b, const Args&... _args)
+ {
+ return max(max(_a, _b), _args...);
+ }
+
+ template<typename Ty, typename... Args>
+ inline constexpr Ty mid(const Ty& _a, const TypeIdentityType<Ty>& _b, const Args&... _args)
{
- return max(min(_a, _b), min(max(_a, _b), _c) );
+ return max(min(_a, _b), min(max(_a, _b), _args...) );
}
template<typename Ty>
- inline constexpr Ty clamp(const Ty& _a, const Ty& _min, const Ty& _max)
+ inline constexpr Ty clamp(const Ty& _a, const TypeIdentityType<Ty>& _min, const TypeIdentityType<Ty>& _max)
{
return max(min(_a, _max), _min);
}
diff --git a/3rdparty/bx/include/bx/inline/cpu.inl b/3rdparty/bx/include/bx/inline/cpu.inl
index 3ff2a231fd3..756aa175682 100644
--- a/3rdparty/bx/include/bx/inline/cpu.inl
+++ b/3rdparty/bx/include/bx/inline/cpu.inl
@@ -1,6 +1,6 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_CPU_H_HEADER_GUARD
@@ -8,11 +8,16 @@
#endif // BX_CPU_H_HEADER_GUARD
#if BX_COMPILER_MSVC
-# if BX_PLATFORM_WINRT
+# if BX_PLATFORM_WINRT || (BX_PLATFORM_WINDOWS && !BX_CPU_X86)
+# ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+# endif // WIN32_LEAN_AND_MEAN
# include <windows.h>
-# endif // BX_PLATFORM_WINRT
+# endif // BX_PLATFORM_WINRT || (BX_PLATFORM_WINDOWS && !BX_CPU_X86)
-# include <emmintrin.h> // _mm_fence
+# if BX_CPU_X86
+# include <emmintrin.h> // _mm_fence
+# endif // BX_CPU_X86
extern "C" void _ReadBarrier();
# pragma intrinsic(_ReadBarrier)
@@ -66,7 +71,7 @@ namespace bx
_ReadBarrier();
#else
asm volatile("":::"memory");
-#endif // BX_COMPILER
+#endif // BX_COMPILER_*
}
inline void writeBarrier()
@@ -75,7 +80,7 @@ namespace bx
_WriteBarrier();
#else
asm volatile("":::"memory");
-#endif // BX_COMPILER
+#endif // BX_COMPILER_*
}
inline void readWriteBarrier()
@@ -84,18 +89,20 @@ namespace bx
_ReadWriteBarrier();
#else
asm volatile("":::"memory");
-#endif // BX_COMPILER
+#endif // BX_COMPILER_*
}
inline void memoryBarrier()
{
-#if BX_PLATFORM_WINRT
- MemoryBarrier();
-#elif BX_COMPILER_MSVC
+#if BX_COMPILER_MSVC
+# if BX_CPU_X86
_mm_mfence();
+# else
+ MemoryBarrier();
+# endif // BX_CPU_X86
#else
__sync_synchronize();
-#endif // BX_COMPILER
+#endif // BX_COMPILER_MSVC
}
template<>
@@ -105,7 +112,7 @@ namespace bx
return int32_t(_InterlockedCompareExchange( (volatile long*)(_ptr), long(_new), long(_old) ) );
#else
return __sync_val_compare_and_swap( (volatile int32_t*)_ptr, _old, _new);
-#endif // BX_COMPILER
+#endif // BX_COMPILER_*
}
template<>
@@ -115,7 +122,7 @@ namespace bx
return uint32_t(_InterlockedCompareExchange( (volatile long*)(_ptr), long(_new), long(_old) ) );
#else
return __sync_val_compare_and_swap( (volatile int32_t*)_ptr, _old, _new);
-#endif // BX_COMPILER
+#endif // BX_COMPILER_*
}
template<>
@@ -125,7 +132,7 @@ namespace bx
return _InterlockedCompareExchange64(_ptr, _new, _old);
#else
return __sync_val_compare_and_swap( (volatile int64_t*)_ptr, _old, _new);
-#endif // BX_COMPILER
+#endif // BX_COMPILER_*
}
template<>
@@ -135,7 +142,7 @@ namespace bx
return uint64_t(_InterlockedCompareExchange64( (volatile int64_t*)(_ptr), int64_t(_new), int64_t(_old) ) );
#else
return __sync_val_compare_and_swap( (volatile int64_t*)_ptr, _old, _new);
-#endif // BX_COMPILER
+#endif // BX_COMPILER_*
}
template<>
@@ -145,7 +152,7 @@ namespace bx
return _InterlockedExchangeAdd( (volatile long*)_ptr, _add);
#else
return __sync_fetch_and_add(_ptr, _add);
-#endif // BX_COMPILER_
+#endif // BX_COMPILER_*
}
template<>
@@ -174,7 +181,7 @@ namespace bx
# endif
#else
return __sync_fetch_and_add(_ptr, _add);
-#endif // BX_COMPILER_
+#endif // BX_COMPILER_*
}
template<>
@@ -190,7 +197,7 @@ namespace bx
return atomicFetchAndAdd(_ptr, _add) + _add;
#else
return __sync_add_and_fetch(_ptr, _add);
-#endif // BX_COMPILER_
+#endif // BX_COMPILER_*
}
template<>
@@ -200,7 +207,7 @@ namespace bx
return atomicFetchAndAdd(_ptr, _add) + _add;
#else
return __sync_add_and_fetch(_ptr, _add);
-#endif // BX_COMPILER_
+#endif // BX_COMPILER_*
}
template<>
@@ -222,7 +229,7 @@ namespace bx
return atomicFetchAndAdd(_ptr, -_sub);
#else
return __sync_fetch_and_sub(_ptr, _sub);
-#endif // BX_COMPILER_
+#endif // BX_COMPILER_*
}
template<>
@@ -232,7 +239,7 @@ namespace bx
return atomicFetchAndAdd(_ptr, -_sub);
#else
return __sync_fetch_and_sub(_ptr, _sub);
-#endif // BX_COMPILER_
+#endif // BX_COMPILER_*
}
template<>
@@ -254,7 +261,7 @@ namespace bx
return atomicFetchAndAdd(_ptr, -_sub) - _sub;
#else
return __sync_sub_and_fetch(_ptr, _sub);
-#endif // BX_COMPILER_
+#endif // BX_COMPILER_*
}
template<>
@@ -264,7 +271,7 @@ namespace bx
return atomicFetchAndAdd(_ptr, -_sub) - _sub;
#else
return __sync_sub_and_fetch(_ptr, _sub);
-#endif // BX_COMPILER_
+#endif // BX_COMPILER_*
}
template<>
@@ -345,7 +352,7 @@ namespace bx
return _InterlockedExchangePointer(_ptr, _new);
#else
return __sync_lock_test_and_set(_ptr, _new);
-#endif // BX_COMPILER
+#endif // BX_COMPILER_*
}
} // namespace bx
diff --git a/3rdparty/bx/include/bx/inline/easing.inl b/3rdparty/bx/include/bx/inline/easing.inl
index 3cdab9a77cb..c484337a776 100644
--- a/3rdparty/bx/include/bx/inline/easing.inl
+++ b/3rdparty/bx/include/bx/inline/easing.inl
@@ -1,6 +1,6 @@
/*
- * Copyright 2011-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2011-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_EASING_H_HEADER_GUARD
diff --git a/3rdparty/bx/include/bx/inline/endian.inl b/3rdparty/bx/include/bx/inline/endian.inl
index 332e2b6102a..eef5e08e7c2 100644
--- a/3rdparty/bx/include/bx/inline/endian.inl
+++ b/3rdparty/bx/include/bx/inline/endian.inl
@@ -1,6 +1,6 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_ENDIAN_H_HEADER_GUARD
@@ -46,7 +46,7 @@ namespace bx
}
template <typename Ty>
- inline Ty toLittleEndian(const Ty _in)
+ inline Ty toLittleEndian(Ty _in)
{
#if BX_CPU_ENDIAN_BIG
return endianSwap(_in);
@@ -56,7 +56,7 @@ namespace bx
}
template <typename Ty>
- inline Ty toBigEndian(const Ty _in)
+ inline Ty toBigEndian(Ty _in)
{
#if BX_CPU_ENDIAN_LITTLE
return endianSwap(_in);
@@ -66,7 +66,7 @@ namespace bx
}
template <typename Ty>
- inline Ty toHostEndian(const Ty _in, bool _fromLittleEndian)
+ inline Ty toHostEndian(Ty _in, bool _fromLittleEndian)
{
#if BX_CPU_ENDIAN_LITTLE
return _fromLittleEndian ? _in : endianSwap(_in);
diff --git a/3rdparty/bx/include/bx/inline/error.inl b/3rdparty/bx/include/bx/inline/error.inl
index af5c31a1991..1379a6cb950 100644
--- a/3rdparty/bx/include/bx/inline/error.inl
+++ b/3rdparty/bx/include/bx/inline/error.inl
@@ -1,12 +1,14 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_ERROR_H_HEADER_GUARD
# error "Must be included from bx/error!"
#endif // BX_ERROR_H_HEADER_GUARD
+#include <bx/debug.h>
+
namespace bx
{
inline Error::Error()
@@ -22,7 +24,7 @@ namespace bx
inline void Error::setError(ErrorResult _errorResult, const StringView& _msg)
{
- BX_CHECK(0 != _errorResult.code, "Invalid ErrorResult passed to setError!");
+ BX_ASSERT(0 != _errorResult.code, "Invalid ErrorResult passed to setError!");
if (!isOk() )
{
@@ -59,15 +61,72 @@ namespace bx
return _rhs.code != m_code;
}
- inline ErrorScope::ErrorScope(Error* _err)
+ inline ErrorIgnore::operator Error*()
+ {
+ return this;
+ }
+
+ inline ErrorAssert::~ErrorAssert()
+ {
+ BX_ASSERT(isOk(), "Error: 0x%08x `%S`"
+ , get().code
+ , &getMessage()
+ );
+ }
+
+ inline ErrorFatal::operator Error*()
+ {
+ return this;
+ }
+
+ inline ErrorFatal::~ErrorFatal()
+ {
+ if (!isOk() )
+ {
+ printf("Error: 0x%08x `%S`"
+ , get().code
+ , &getMessage()
+ );
+
+ exit(kExitFailure);
+ }
+ }
+
+ inline ErrorAssert::operator Error*()
+ {
+ return this;
+ }
+
+ inline ErrorScope::ErrorScope(Error* _err, const StringView& _name)
: m_err(_err)
+ , m_name(_name)
{
- BX_CHECK(NULL != _err, "_err can't be NULL");
+ BX_UNUSED(m_err);
+ BX_ASSERT(NULL != _err, "_err can't be NULL");
}
inline ErrorScope::~ErrorScope()
{
- BX_CHECK(m_err->isOk(), "Error: %d", m_err->get().code);
+ if (m_name.isEmpty() )
+ {
+ BX_ASSERT(m_err->isOk(), "Error: 0x%08x `%S`"
+ , m_err->get().code
+ , &m_err->getMessage()
+ );
+ }
+ else
+ {
+ BX_ASSERT(m_err->isOk(), "Error: %S - 0x%08x `%S`"
+ , &m_name
+ , m_err->get().code
+ , &m_err->getMessage()
+ );
+ }
+ }
+
+ inline const StringView& ErrorScope::getName() const
+ {
+ return m_name;
}
} // namespace bx
diff --git a/3rdparty/bx/include/bx/inline/float4x4_t.inl b/3rdparty/bx/include/bx/inline/float4x4_t.inl
index 222c111c361..3860d033ecb 100644
--- a/3rdparty/bx/include/bx/inline/float4x4_t.inl
+++ b/3rdparty/bx/include/bx/inline/float4x4_t.inl
@@ -1,6 +1,6 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_FLOAT4X4_H_HEADER_GUARD
@@ -40,10 +40,99 @@ namespace bx
BX_SIMD_INLINE void float4x4_mul(float4x4_t* _result, const float4x4_t* _a, const float4x4_t* _b)
{
+#if BX_CONFIG_SUPPORTS_SIMD
_result->col[0] = simd_mul(_a->col[0], _b);
_result->col[1] = simd_mul(_a->col[1], _b);
_result->col[2] = simd_mul(_a->col[2], _b);
_result->col[3] = simd_mul(_a->col[3], _b);
+#else
+ const float* aa = (const float*)_a;
+ const float* bb = (const float*)_b;
+ float *rr = (float*)_result;
+
+ rr[ 0] = aa[ 0]*bb[ 0] + aa[ 1]*bb[ 4] + aa[ 2]*bb[ 8] + aa[ 3]*bb[12];
+ rr[ 1] = aa[ 0]*bb[ 1] + aa[ 1]*bb[ 5] + aa[ 2]*bb[ 9] + aa[ 3]*bb[13];
+ rr[ 2] = aa[ 0]*bb[ 2] + aa[ 1]*bb[ 6] + aa[ 2]*bb[10] + aa[ 3]*bb[14];
+ rr[ 3] = aa[ 0]*bb[ 3] + aa[ 1]*bb[ 7] + aa[ 2]*bb[11] + aa[ 3]*bb[15];
+
+ rr[ 4] = aa[ 4]*bb[ 0] + aa[ 5]*bb[ 4] + aa[ 6]*bb[ 8] + aa[ 7]*bb[12];
+ rr[ 5] = aa[ 4]*bb[ 1] + aa[ 5]*bb[ 5] + aa[ 6]*bb[ 9] + aa[ 7]*bb[13];
+ rr[ 6] = aa[ 4]*bb[ 2] + aa[ 5]*bb[ 6] + aa[ 6]*bb[10] + aa[ 7]*bb[14];
+ rr[ 7] = aa[ 4]*bb[ 3] + aa[ 5]*bb[ 7] + aa[ 6]*bb[11] + aa[ 7]*bb[15];
+
+ rr[ 8] = aa[ 8]*bb[ 0] + aa[ 9]*bb[ 4] + aa[10]*bb[ 8] + aa[11]*bb[12];
+ rr[ 9] = aa[ 8]*bb[ 1] + aa[ 9]*bb[ 5] + aa[10]*bb[ 9] + aa[11]*bb[13];
+ rr[10] = aa[ 8]*bb[ 2] + aa[ 9]*bb[ 6] + aa[10]*bb[10] + aa[11]*bb[14];
+ rr[11] = aa[ 8]*bb[ 3] + aa[ 9]*bb[ 7] + aa[10]*bb[11] + aa[11]*bb[15];
+
+ rr[12] = aa[12]*bb[ 0] + aa[13]*bb[ 4] + aa[14]*bb[ 8] + aa[15]*bb[12];
+ rr[13] = aa[12]*bb[ 1] + aa[13]*bb[ 5] + aa[14]*bb[ 9] + aa[15]*bb[13];
+ rr[14] = aa[12]*bb[ 2] + aa[13]*bb[ 6] + aa[14]*bb[10] + aa[15]*bb[14];
+ rr[15] = aa[12]*bb[ 3] + aa[13]*bb[ 7] + aa[14]*bb[11] + aa[15]*bb[15];
+#endif // BX_CONFIG_SUPPORTS_SIMD
+ }
+
+ BX_SIMD_INLINE void model4x4_mul(float4x4_t* _result, const float4x4_t* _a, const float4x4_t* _b)
+ {
+#if BX_CONFIG_SUPPORTS_SIMD
+ // With SIMD faster to do the general 4x4 form:
+ float4x4_mul(_result, _a, _b);
+#else
+ const float* aa = (const float*)_a; // aa[ 3] == aa[ 7] == aa[11] == 0.0f, aa[15] = 1.0f
+ const float* bb = (const float*)_b; // bb[ 3] == bb[ 7] == bb[11] == 0.0f, bb[15] = 1.0f
+ float *rr = (float*)_result;
+
+ rr[ 0] = aa[ 0]*bb[ 0] + aa[ 1]*bb[ 4] + aa[ 2]*bb[ 8];
+ rr[ 1] = aa[ 0]*bb[ 1] + aa[ 1]*bb[ 5] + aa[ 2]*bb[ 9];
+ rr[ 2] = aa[ 0]*bb[ 2] + aa[ 1]*bb[ 6] + aa[ 2]*bb[10];
+ rr[ 3] = 0.0f;
+
+ rr[ 4] = aa[ 4]*bb[ 0] + aa[ 5]*bb[ 4] + aa[ 6]*bb[ 8];
+ rr[ 5] = aa[ 4]*bb[ 1] + aa[ 5]*bb[ 5] + aa[ 6]*bb[ 9];
+ rr[ 6] = aa[ 4]*bb[ 2] + aa[ 5]*bb[ 6] + aa[ 6]*bb[10];
+ rr[ 7] = 0.0f;
+
+ rr[ 8] = aa[ 8]*bb[ 0] + aa[ 9]*bb[ 4] + aa[10]*bb[ 8];
+ rr[ 9] = aa[ 8]*bb[ 1] + aa[ 9]*bb[ 5] + aa[10]*bb[ 9];
+ rr[10] = aa[ 8]*bb[ 2] + aa[ 9]*bb[ 6] + aa[10]*bb[10];
+ rr[11] = 0.0f;
+
+ rr[12] = aa[12]*bb[ 0] + aa[13]*bb[ 4] + aa[14]*bb[ 8] + bb[12];
+ rr[13] = aa[12]*bb[ 1] + aa[13]*bb[ 5] + aa[14]*bb[ 9] + bb[13];
+ rr[14] = aa[12]*bb[ 2] + aa[13]*bb[ 6] + aa[14]*bb[10] + bb[14];
+ rr[15] = 1.0f;
+#endif // BX_CONFIG_SUPPORTS_SIMD
+ }
+
+ BX_SIMD_INLINE void model4x4_mul_viewproj4x4(float4x4_t* _result, const float4x4_t* _model, const float4x4_t* _viewProj)
+ {
+#if BX_CONFIG_SUPPORTS_SIMD
+ // With SIMD faster to do the general 4x4 form:
+ float4x4_mul(_result, _model, _viewProj);
+#else
+ const float* aa = (const float*)_model; // aa[ 3] == aa[ 7] == aa[11] == 0.0f, aa[15] == 1.0f
+ const float* bb = (const float*)_viewProj;
+ float *rr = (float*)_result;
+ rr[ 0] = aa[ 0]*bb[ 0] + aa[ 1]*bb[ 4] + aa[ 2]*bb[ 8];
+ rr[ 1] = aa[ 0]*bb[ 1] + aa[ 1]*bb[ 5] + aa[ 2]*bb[ 9];
+ rr[ 2] = aa[ 0]*bb[ 2] + aa[ 1]*bb[ 6] + aa[ 2]*bb[10];
+ rr[ 3] = aa[ 0]*bb[ 3] + aa[ 1]*bb[ 7] + aa[ 2]*bb[11];
+
+ rr[ 4] = aa[ 4]*bb[ 0] + aa[ 5]*bb[ 4] + aa[ 6]*bb[ 8];
+ rr[ 5] = aa[ 4]*bb[ 1] + aa[ 5]*bb[ 5] + aa[ 6]*bb[ 9];
+ rr[ 6] = aa[ 4]*bb[ 2] + aa[ 5]*bb[ 6] + aa[ 6]*bb[10];
+ rr[ 7] = aa[ 4]*bb[ 3] + aa[ 5]*bb[ 7] + aa[ 6]*bb[11];
+
+ rr[ 8] = aa[ 8]*bb[ 0] + aa[ 9]*bb[ 4] + aa[10]*bb[ 8];
+ rr[ 9] = aa[ 8]*bb[ 1] + aa[ 9]*bb[ 5] + aa[10]*bb[ 9];
+ rr[10] = aa[ 8]*bb[ 2] + aa[ 9]*bb[ 6] + aa[10]*bb[10];
+ rr[11] = aa[ 8]*bb[ 3] + aa[ 9]*bb[ 7] + aa[10]*bb[11];
+
+ rr[12] = aa[12]*bb[ 0] + aa[13]*bb[ 4] + aa[14]*bb[ 8] + bb[12];
+ rr[13] = aa[12]*bb[ 1] + aa[13]*bb[ 5] + aa[14]*bb[ 9] + bb[13];
+ rr[14] = aa[12]*bb[ 2] + aa[13]*bb[ 6] + aa[14]*bb[10] + bb[14];
+ rr[15] = aa[12]*bb[ 3] + aa[13]*bb[ 7] + aa[14]*bb[11] + bb[15];
+#endif // BX_CONFIG_SUPPORTS_SIMD
}
BX_SIMD_FORCE_INLINE void float4x4_transpose(float4x4_t* _result, const float4x4_t* _mtx)
diff --git a/3rdparty/bx/include/bx/inline/handlealloc.inl b/3rdparty/bx/include/bx/inline/handlealloc.inl
index 3bb364b66b3..7051692587b 100644
--- a/3rdparty/bx/include/bx/inline/handlealloc.inl
+++ b/3rdparty/bx/include/bx/inline/handlealloc.inl
@@ -1,6 +1,6 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_HANDLE_ALLOC_H_HEADER_GUARD
@@ -186,7 +186,7 @@ namespace bx
template <uint16_t MaxHandlesT>
inline uint16_t HandleListT<MaxHandlesT>::getNext(uint16_t _handle) const
{
- BX_CHECK(isValid(_handle), "Invalid handle %d!", _handle);
+ BX_ASSERT(isValid(_handle), "Invalid handle %d!", _handle);
const Link& curr = m_links[_handle];
return curr.m_next;
}
@@ -194,7 +194,7 @@ namespace bx
template <uint16_t MaxHandlesT>
inline uint16_t HandleListT<MaxHandlesT>::getPrev(uint16_t _handle) const
{
- BX_CHECK(isValid(_handle), "Invalid handle %d!", _handle);
+ BX_ASSERT(isValid(_handle), "Invalid handle %d!", _handle);
const Link& curr = m_links[_handle];
return curr.m_prev;
}
@@ -202,7 +202,7 @@ namespace bx
template <uint16_t MaxHandlesT>
inline void HandleListT<MaxHandlesT>::remove(uint16_t _handle)
{
- BX_CHECK(isValid(_handle), "Invalid handle %d!", _handle);
+ BX_ASSERT(isValid(_handle), "Invalid handle %d!", _handle);
Link& curr = m_links[_handle];
if (kInvalidHandle != curr.m_prev)
@@ -358,7 +358,7 @@ namespace bx
template <uint16_t MaxHandlesT>
inline void HandleAllocLruT<MaxHandlesT>::free(uint16_t _handle)
{
- BX_CHECK(isValid(_handle), "Invalid handle %d!", _handle);
+ BX_ASSERT(isValid(_handle), "Invalid handle %d!", _handle);
m_list.remove(_handle);
m_alloc.free(_handle);
}
@@ -366,7 +366,7 @@ namespace bx
template <uint16_t MaxHandlesT>
inline void HandleAllocLruT<MaxHandlesT>::touch(uint16_t _handle)
{
- BX_CHECK(isValid(_handle), "Invalid handle %d!", _handle);
+ BX_ASSERT(isValid(_handle), "Invalid handle %d!", _handle);
m_list.remove(_handle);
m_list.pushFront(_handle);
}
diff --git a/3rdparty/bx/include/bx/inline/hash.inl b/3rdparty/bx/include/bx/inline/hash.inl
index 18bee143c70..bad8ba0b5e1 100644
--- a/3rdparty/bx/include/bx/inline/hash.inl
+++ b/3rdparty/bx/include/bx/inline/hash.inl
@@ -1,6 +1,6 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_HASH_H_HEADER_GUARD
@@ -9,171 +9,89 @@
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)
+ inline void HashAdler32::begin()
{
- m_hash = _seed;
- m_tail = 0;
- m_count = 0;
- m_size = 0;
+ m_a = 1;
+ m_b = 0;
}
- inline void HashMurmur2A::add(const void* _data, int _len)
+ inline void HashAdler32::add(const void* _data, int32_t _len)
{
- if (BX_UNLIKELY(!isAligned(_data, 4) ) )
- {
- addUnaligned(_data, _len);
- return;
- }
-
- addAligned(_data, _len);
- }
+ constexpr uint32_t kModAdler = 65521;
- 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)
+ for (; _len != 0; --_len)
{
- uint32_t kk = *(uint32_t*)data;
-
- mmix(m_hash, kk);
-
- data += 4;
- _len -= 4;
+ m_a = (m_a + *data++) % kModAdler;
+ m_b = (m_b + m_a ) % kModAdler;
}
-
- mixTail(data, _len);
}
- inline void HashMurmur2A::addUnaligned(const void* _data, int _len)
+ inline void HashAdler32::add(const char* _data)
{
- 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;
- }
+ return add(StringView(_data) );
+ }
- mixTail(data, _len);
+ inline void HashAdler32::add(const StringView& _data)
+ {
+ return add(_data.getPtr(), _data.getLength() );
}
template<typename Ty>
- inline void HashMurmur2A::add(Ty _value)
+ inline void HashAdler32::add(const Ty& _data)
{
- add(&_value, sizeof(Ty) );
+ add(&_data, sizeof(Ty) );
}
- inline uint32_t HashMurmur2A::end()
+ inline uint32_t HashAdler32::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;
+ return m_a | (m_b<<16);
}
- inline void HashMurmur2A::readUnaligned(const void* _data, uint32_t& _out)
+ inline void HashCrc32::add(const char* _data)
{
- 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
- ;
- }
+ return add(StringView(_data) );
}
- inline void HashMurmur2A::mixTail(const uint8_t*& _data, int& _len)
+ inline void HashCrc32::add(const StringView& _data)
{
- 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;
- }
- }
+ return add(_data.getPtr(), _data.getLength() );
}
-#undef MURMUR_M
-#undef MURMUR_R
-#undef mmix
-
- inline void HashAdler32::begin()
+ template<typename Ty>
+ inline void HashCrc32::add(const Ty& _data)
{
- m_a = 1;
- m_b = 0;
+ add(&_data, sizeof(Ty) );
}
- inline void HashAdler32::add(const void* _data, int _len)
+ inline uint32_t HashCrc32::end()
{
- const uint32_t kModAdler = 65521;
- const uint8_t* data = (const uint8_t*)_data;
- for (; _len != 0; --_len)
- {
- m_a = (m_a + *data++) % kModAdler;
- m_b = (m_b + m_a ) % kModAdler;
- }
+ m_hash ^= UINT32_MAX;
+ return m_hash;
}
- template<typename Ty>
- inline void HashAdler32::add(Ty _value)
+ inline void HashMurmur2A::begin(uint32_t _seed)
{
- add(&_value, sizeof(Ty) );
+ m_hash = _seed;
+ m_tail = 0;
+ m_count = 0;
+ m_size = 0;
}
- inline uint32_t HashAdler32::end()
+ inline void HashMurmur2A::add(const char* _data)
{
- return m_a | (m_b<<16);
+ return add(StringView(_data) );
}
- template<typename Ty>
- inline void HashCrc32::add(Ty _value)
+ inline void HashMurmur2A::add(const StringView& _data)
{
- add(&_value, sizeof(Ty) );
+ return add(_data.getPtr(), _data.getLength() );
}
- inline uint32_t HashCrc32::end()
+ template<typename Ty>
+ inline void HashMurmur2A::add(const Ty& _data)
{
- m_hash ^= UINT32_MAX;
- return m_hash;
+ add(&_data, sizeof(Ty) );
}
template<typename HashT>
@@ -181,15 +99,14 @@ namespace bx
{
HashT hh;
hh.begin();
- hh.add(_data, (int)_size);
+ hh.add(_data, (int32_t)_size);
return hh.end();
}
- template<typename HashT, typename Ty>
- inline uint32_t hash(const Ty& _data)
+ template<typename HashT>
+ inline uint32_t hash(const char* _data)
{
- BX_STATIC_ASSERT(isTriviallyCopyable<Ty>() );
- return hash<HashT>(&_data, sizeof(Ty) );
+ return hash<HashT>(StringView(_data) );
}
template<typename HashT>
@@ -198,10 +115,11 @@ namespace bx
return hash<HashT>(_data.getPtr(), _data.getLength() );
}
- template<typename HashT>
- inline uint32_t hash(const char* _data)
+ template<typename HashT, typename Ty>
+ inline uint32_t hash(const Ty& _data)
{
- return hash<HashT>(StringView(_data) );
+ BX_STATIC_ASSERT(isTriviallyCopyable<Ty>() );
+ return hash<HashT>(&_data, sizeof(Ty) );
}
} // namespace bx
diff --git a/3rdparty/bx/include/bx/inline/math.inl b/3rdparty/bx/include/bx/inline/math.inl
index 29c88797e94..df433fc6e67 100644
--- a/3rdparty/bx/include/bx/inline/math.inl
+++ b/3rdparty/bx/include/bx/inline/math.inl
@@ -1,6 +1,6 @@
/*
- * Copyright 2011-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2011-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
// FPU math lib
@@ -10,6 +10,7 @@
#endif // BX_MATH_H_HEADER_GUARD
#include <bx/simd_t.h>
+#include <bx/uint32_t.h>
namespace bx
{
@@ -95,24 +96,46 @@ namespace bx
return tmp == UINT64_C(0x7ff0000000000000);
}
- inline BX_CONST_FUNC float round(float _f)
+ inline BX_CONSTEXPR_FUNC float floor(float _a)
{
- return floor(_f + 0.5f);
+ if (_a < 0.0f)
+ {
+ const float fr = fract(-_a);
+ const float tr = trunc(-_a);
+
+ return -tr - float(0.0f != fr);
+ }
+
+ return _a - fract(_a);
}
- inline BX_CONST_FUNC float ceil(float _a)
+ inline BX_CONSTEXPR_FUNC float ceil(float _a)
{
return -floor(-_a);
}
+ inline BX_CONSTEXPR_FUNC float round(float _f)
+ {
+ return floor(_f + 0.5f);
+ }
+
inline BX_CONSTEXPR_FUNC float lerp(float _a, float _b, float _t)
{
- return _a + (_b - _a) * _t;
+ // Reference(s):
+ // - Linear interpolation past, present and future
+ // https://web.archive.org/web/20200404165201/https://fgiesen.wordpress.com/2012/08/15/linear-interpolation-past-present-and-future/
+ //
+ return mad(_t, _b, nms(_t, _a, _a) );
+ }
+
+ inline BX_CONSTEXPR_FUNC float invLerp(float _a, float _b, float _value)
+ {
+ return (_value - _a) / (_b - _a);
}
inline BX_CONSTEXPR_FUNC float sign(float _a)
{
- return _a < 0.0f ? -1.0f : 1.0f;
+ return float( (0.0f < _a) - (0.0f > _a) );
}
inline BX_CONSTEXPR_FUNC float abs(float _a)
@@ -175,11 +198,18 @@ namespace bx
return pow(2.0f, _a);
}
+ template<>
inline BX_CONST_FUNC float log2(float _a)
{
return log(_a) * kInvLogNat2;
}
+ template<>
+ inline BX_CONST_FUNC int32_t log2(int32_t _a)
+ {
+ return 31 - uint32_cntlz(_a);
+ }
+
inline BX_CONST_FUNC float rsqrtRef(float _a)
{
return pow(_a, -0.5f);
@@ -248,9 +278,34 @@ namespace bx
return _a - trunc(_a);
}
+ inline BX_CONSTEXPR_FUNC float nms(float _a, float _b, float _c)
+ {
+ return _c - _a * _b;
+ }
+
+ inline BX_CONSTEXPR_FUNC float add(float _a, float _b)
+ {
+ return _a + _b;
+ }
+
+ inline BX_CONSTEXPR_FUNC float sub(float _a, float _b)
+ {
+ return _a - _b;
+ }
+
+ inline BX_CONSTEXPR_FUNC float mul(float _a, float _b)
+ {
+ return _a * _b;
+ }
+
inline BX_CONSTEXPR_FUNC float mad(float _a, float _b, float _c)
{
- return _a * _b + _c;
+ return add(mul(_a, _b), _c);
+ }
+
+ inline BX_CONSTEXPR_FUNC float rcp(float _a)
+ {
+ return 1.0f / _a;
}
inline BX_CONST_FUNC float mod(float _a, float _b)
@@ -258,22 +313,23 @@ namespace bx
return _a - _b * floor(_a / _b);
}
- inline BX_CONSTEXPR_FUNC bool equal(float _a, float _b, float _epsilon)
+ inline BX_CONSTEXPR_FUNC bool isEqual(float _a, float _b, float _epsilon)
{
// Reference(s):
- // - https://web.archive.org/web/20181103180318/http://realtimecollisiondetection.net/blog/?p=89
+ // - Floating-point tolerances revisited
+ // https://web.archive.org/web/20181103180318/http://realtimecollisiondetection.net/blog/?p=89
//
const float lhs = abs(_a - _b);
const float rhs = _epsilon * max(1.0f, abs(_a), abs(_b) );
return lhs <= rhs;
}
- inline BX_CONST_FUNC bool equal(const float* _a, const float* _b, uint32_t _num, float _epsilon)
+ inline BX_CONST_FUNC bool isEqual(const float* _a, const float* _b, uint32_t _num, float _epsilon)
{
- bool result = equal(_a[0], _b[0], _epsilon);
+ bool result = isEqual(_a[0], _b[0], _epsilon);
for (uint32_t ii = 1; result && ii < _num; ++ii)
{
- result = equal(_a[ii], _b[ii], _epsilon);
+ result = isEqual(_a[ii], _b[ii], _epsilon);
}
return result;
}
@@ -300,6 +356,11 @@ namespace bx
return square(_a)*(3.0f - 2.0f*_a);
}
+ inline BX_CONST_FUNC float invSmoothStep(float _a)
+ {
+ return 0.5f - sin(asin(1.0f - 2.0f * _a) / 3.0f);
+ }
+
inline BX_CONSTEXPR_FUNC float bias(float _time, float _bias)
{
return _time / ( ( (1.0f/_bias - 2.0f)*(1.0f - _time) ) + 1.0f);
@@ -331,26 +392,114 @@ namespace bx
return _a + angleDiff(_a, _b) * _t;
}
- inline Vec3 load(const void* _ptr)
+ template<typename Ty>
+ inline Ty load(const void* _ptr)
{
- const float* ptr = reinterpret_cast<const float*>(_ptr);
- return
- {
- ptr[0],
- ptr[1],
- ptr[2],
- };
+ Ty result(init::None);
+ memCopy(&result, _ptr, sizeof(Ty) );
+ return result;
+ }
+
+ template<typename Ty>
+ inline void store(void* _ptr, const Ty& _a)
+ {
+ memCopy(_ptr, &_a, sizeof(Ty) );
}
- inline void store(void* _ptr, const Vec3& _a)
+ inline Vec3::Vec3(init::NoneTag)
{
- float* ptr = reinterpret_cast<float*>(_ptr);
- ptr[0] = _a.x;
- ptr[1] = _a.y;
- ptr[2] = _a.z;
}
- inline BX_CONSTEXPR_FUNC Vec3 abs(const Vec3& _a)
+ constexpr Vec3::Vec3(init::ZeroTag)
+ : x(0.0f)
+ , y(0.0f)
+ , z(0.0f)
+ {
+ }
+
+ constexpr Vec3::Vec3(init::IdentityTag)
+ : x(0.0f)
+ , y(0.0f)
+ , z(0.0f)
+ {
+ }
+
+ constexpr Vec3::Vec3(float _v)
+ : x(_v)
+ , y(_v)
+ , z(_v)
+ {
+ }
+
+ constexpr Vec3::Vec3(float _x, float _y, float _z)
+ : x(_x)
+ , y(_y)
+ , z(_z)
+ {
+ }
+
+ inline Plane::Plane(init::NoneTag)
+ : normal(init::None)
+ {
+ }
+
+ constexpr Plane::Plane(init::ZeroTag)
+ : normal(init::Zero)
+ , dist(0.0f)
+ {
+ }
+
+ constexpr Plane::Plane(init::IdentityTag)
+ : normal(0.0f, 1.0f, 0.0f)
+ , dist(0.0f)
+ {
+ }
+
+ constexpr Plane::Plane(Vec3 _normal, float _dist)
+ : normal(_normal)
+ , dist(_dist)
+ {
+ }
+
+ inline Quaternion::Quaternion(init::NoneTag)
+ {
+ }
+
+ constexpr Quaternion::Quaternion(init::ZeroTag)
+ : x(0.0f)
+ , y(0.0f)
+ , z(0.0f)
+ , w(0.0f)
+ {
+ }
+
+ constexpr Quaternion::Quaternion(init::IdentityTag)
+ : x(0.0f)
+ , y(0.0f)
+ , z(0.0f)
+ , w(1.0f)
+ {
+ }
+
+ constexpr Quaternion::Quaternion(float _x, float _y, float _z, float _w)
+ : x(_x)
+ , y(_y)
+ , z(_z)
+ , w(_w)
+ {
+ }
+
+ inline BX_CONSTEXPR_FUNC Vec3 round(const Vec3 _a)
+ {
+ return
+ {
+ round(_a.x),
+ round(_a.y),
+ round(_a.z),
+ };
+ }
+
+ inline BX_CONSTEXPR_FUNC Vec3 abs(const Vec3 _a)
{
return
{
@@ -360,7 +509,7 @@ namespace bx
};
}
- inline BX_CONSTEXPR_FUNC Vec3 neg(const Vec3& _a)
+ inline BX_CONSTEXPR_FUNC Vec3 neg(const Vec3 _a)
{
return
{
@@ -370,7 +519,7 @@ namespace bx
};
}
- inline BX_CONSTEXPR_FUNC Vec3 add(const Vec3& _a, const Vec3& _b)
+ inline BX_CONSTEXPR_FUNC Vec3 add(const Vec3 _a, const Vec3 _b)
{
return
{
@@ -380,7 +529,7 @@ namespace bx
};
}
- inline BX_CONSTEXPR_FUNC Vec3 add(const Vec3& _a, float _b)
+ inline BX_CONSTEXPR_FUNC Vec3 add(const Vec3 _a, float _b)
{
return
{
@@ -390,7 +539,7 @@ namespace bx
};
}
- inline BX_CONSTEXPR_FUNC Vec3 sub(const Vec3& _a, const Vec3& _b)
+ inline BX_CONSTEXPR_FUNC Vec3 sub(const Vec3 _a, const Vec3 _b)
{
return
{
@@ -400,7 +549,7 @@ namespace bx
};
}
- inline BX_CONSTEXPR_FUNC Vec3 sub(const Vec3& _a, float _b)
+ inline BX_CONSTEXPR_FUNC Vec3 sub(const Vec3 _a, float _b)
{
return
{
@@ -410,7 +559,7 @@ namespace bx
};
}
- inline BX_CONSTEXPR_FUNC Vec3 mul(const Vec3& _a, const Vec3& _b)
+ inline BX_CONSTEXPR_FUNC Vec3 mul(const Vec3 _a, const Vec3 _b)
{
return
{
@@ -420,7 +569,7 @@ namespace bx
};
}
- inline BX_CONSTEXPR_FUNC Vec3 mul(const Vec3& _a, float _b)
+ inline BX_CONSTEXPR_FUNC Vec3 mul(const Vec3 _a, float _b)
{
return
{
@@ -430,17 +579,42 @@ namespace bx
};
}
- inline BX_CONSTEXPR_FUNC Vec3 mad(const Vec3& _a, const Vec3& _b, const Vec3& _c)
+ inline BX_CONSTEXPR_FUNC Vec3 div(const Vec3 _a, const Vec3 _b)
+ {
+ return mul(_a, rcp(_b) );
+ }
+
+ inline BX_CONSTEXPR_FUNC Vec3 div(const Vec3 _a, float _b)
+ {
+ return mul(_a, rcp(_b) );
+ }
+
+ inline BX_CONSTEXPR_FUNC Vec3 nms(const Vec3 _a, const float _b, const Vec3 _c)
+ {
+ return sub(_c, mul(_a, _b) );
+ }
+
+ inline BX_CONSTEXPR_FUNC Vec3 nms(const Vec3 _a, const Vec3 _b, const Vec3 _c)
+ {
+ return sub(_c, mul(_a, _b) );
+ }
+
+ inline BX_CONSTEXPR_FUNC Vec3 mad(const Vec3 _a, const float _b, const Vec3 _c)
+ {
+ return add(mul(_a, _b), _c);
+ }
+
+ inline BX_CONSTEXPR_FUNC Vec3 mad(const Vec3 _a, const Vec3 _b, const Vec3 _c)
{
return add(mul(_a, _b), _c);
}
- inline BX_CONSTEXPR_FUNC float dot(const Vec3& _a, const Vec3& _b)
+ inline BX_CONSTEXPR_FUNC float dot(const Vec3 _a, const Vec3 _b)
{
return _a.x*_b.x + _a.y*_b.y + _a.z*_b.z;
}
- inline BX_CONSTEXPR_FUNC Vec3 cross(const Vec3& _a, const Vec3& _b)
+ inline BX_CONSTEXPR_FUNC Vec3 cross(const Vec3 _a, const Vec3 _b)
{
return
{
@@ -450,12 +624,23 @@ namespace bx
};
}
- inline BX_CONST_FUNC float length(const Vec3& _a)
+ inline BX_CONST_FUNC float length(const Vec3 _a)
{
return sqrt(dot(_a, _a) );
}
- inline BX_CONSTEXPR_FUNC Vec3 lerp(const Vec3& _a, const Vec3& _b, float _t)
+ inline BX_CONST_FUNC float distanceSq(const Vec3 _a, const Vec3 _b)
+ {
+ const Vec3 ba = sub(_b, _a);
+ return dot(ba, ba);
+ }
+
+ inline BX_CONST_FUNC float distance(const Vec3 _a, const Vec3 _b)
+ {
+ return length(sub(_b, _a) );
+ }
+
+ inline BX_CONSTEXPR_FUNC Vec3 lerp(const Vec3 _a, const Vec3 _b, float _t)
{
return
{
@@ -465,7 +650,7 @@ namespace bx
};
}
- inline BX_CONSTEXPR_FUNC Vec3 lerp(const Vec3& _a, const Vec3& _b, const Vec3& _t)
+ inline BX_CONSTEXPR_FUNC Vec3 lerp(const Vec3 _a, const Vec3 _b, const Vec3 _t)
{
return
{
@@ -475,14 +660,14 @@ namespace bx
};
}
- inline BX_CONST_FUNC Vec3 normalize(const Vec3& _a)
+ inline BX_CONST_FUNC Vec3 normalize(const Vec3 _a)
{
const float invLen = 1.0f/length(_a);
- const Vec3 result = mul(_a, invLen);
+ const Vec3 result = mul(_a, invLen);
return result;
}
- inline BX_CONSTEXPR_FUNC Vec3 min(const Vec3& _a, const Vec3& _b)
+ inline BX_CONSTEXPR_FUNC Vec3 min(const Vec3 _a, const Vec3 _b)
{
return
{
@@ -492,7 +677,7 @@ namespace bx
};
}
- inline BX_CONSTEXPR_FUNC Vec3 max(const Vec3& _a, const Vec3& _b)
+ inline BX_CONSTEXPR_FUNC Vec3 max(const Vec3 _a, const Vec3 _b)
{
return
{
@@ -502,7 +687,7 @@ namespace bx
};
}
- inline BX_CONSTEXPR_FUNC Vec3 rcp(const Vec3& _a)
+ inline BX_CONSTEXPR_FUNC Vec3 rcp(const Vec3 _a)
{
return
{
@@ -512,7 +697,15 @@ namespace bx
};
}
- inline void calcTangentFrame(Vec3& _outT, Vec3& _outB, const Vec3& _n)
+ inline BX_CONSTEXPR_FUNC bool isEqual(const Vec3 _a, const Vec3 _b, float _epsilon)
+ {
+ return isEqual(_a.x, _b.x, _epsilon)
+ && isEqual(_a.y, _b.y, _epsilon)
+ && isEqual(_a.z, _b.z, _epsilon)
+ ;
+ }
+
+ inline void calcTangentFrame(Vec3& _outT, Vec3& _outB, const Vec3 _n)
{
const float nx = _n.x;
const float ny = _n.y;
@@ -536,7 +729,7 @@ namespace bx
_outB = cross(_n, _outT);
}
- inline void calcTangentFrame(Vec3& _outT, Vec3& _outB, const Vec3& _n, float _angle)
+ inline void calcTangentFrame(Vec3& _outT, Vec3& _outB, const Vec3 _n, float _angle)
{
calcTangentFrame(_outT, _outB, _n);
@@ -552,7 +745,7 @@ namespace bx
inline BX_CONST_FUNC Vec3 fromLatLong(float _u, float _v)
{
- Vec3 result;
+ Vec3 result(init::None);
const float phi = _u * kPi2;
const float theta = _v * kPi;
@@ -567,292 +760,317 @@ namespace bx
return result;
}
- inline void toLatLong(float* _outU, float* _outV, const Vec3& _dir)
+ inline void toLatLong(float* _outU, float* _outV, const Vec3 _dir)
{
const float phi = atan2(_dir.x, _dir.z);
const float theta = acos(_dir.y);
- *_outU = (bx::kPi + phi)/bx::kPi2;
- *_outV = theta*bx::kInvPi;
+ *_outU = (kPi + phi)/kPi2;
+ *_outV = theta*kInvPi;
}
- inline void vec3Add(float* _result, const float* _a, const float* _b)
+ inline BX_CONSTEXPR_FUNC Quaternion invert(const Quaternion _a)
{
- _result[0] = _a[0] + _b[0];
- _result[1] = _a[1] + _b[1];
- _result[2] = _a[2] + _b[2];
+ return
+ {
+ -_a.x,
+ -_a.y,
+ -_a.z,
+ _a.w,
+ };
}
- inline void vec3Sub(float* _result, const float* _a, const float* _b)
+ inline BX_CONSTEXPR_FUNC Vec3 mulXyz(const Quaternion _a, const Quaternion _b)
{
- _result[0] = _a[0] - _b[0];
- _result[1] = _a[1] - _b[1];
- _result[2] = _a[2] - _b[2];
+ const float ax = _a.x;
+ const float ay = _a.y;
+ const float az = _a.z;
+ const float aw = _a.w;
+
+ const float bx = _b.x;
+ const float by = _b.y;
+ const float bz = _b.z;
+ const float bw = _b.w;
+
+ return
+ {
+ aw * bx + ax * bw + ay * bz - az * by,
+ aw * by - ax * bz + ay * bw + az * bx,
+ aw * bz + ax * by - ay * bx + az * bw,
+ };
}
- inline void vec3Mul(float* _result, const float* _a, const float* _b)
+ inline BX_CONSTEXPR_FUNC Quaternion add(const Quaternion _a, const Quaternion _b)
{
- _result[0] = _a[0] * _b[0];
- _result[1] = _a[1] * _b[1];
- _result[2] = _a[2] * _b[2];
+ return
+ {
+ _a.x + _b.x,
+ _a.y + _b.y,
+ _a.z + _b.z,
+ _a.w + _b.w,
+ };
}
- inline void vec3Mul(float* _result, const float* _a, float _b)
+ inline BX_CONSTEXPR_FUNC Quaternion sub(const Quaternion _a, const Quaternion _b)
{
- _result[0] = _a[0] * _b;
- _result[1] = _a[1] * _b;
- _result[2] = _a[2] * _b;
+ return
+ {
+ _a.x - _b.x,
+ _a.y - _b.y,
+ _a.z - _b.z,
+ _a.w - _b.w,
+ };
}
- inline float vec3Dot(const float* _a, const float* _b)
+ inline BX_CONSTEXPR_FUNC Quaternion mul(const Quaternion _a, float _b)
{
- return _a[0]*_b[0] + _a[1]*_b[1] + _a[2]*_b[2];
+ return
+ {
+ _a.x * _b,
+ _a.y * _b,
+ _a.z * _b,
+ _a.w * _b,
+ };
}
- inline void vec3Cross(float* _result, const float* _a, const float* _b)
+ inline BX_CONSTEXPR_FUNC Quaternion mul(const Quaternion _a, const Quaternion _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];
+ const float ax = _a.x;
+ const float ay = _a.y;
+ const float az = _a.z;
+ const float aw = _a.w;
+
+ const float bx = _b.x;
+ const float by = _b.y;
+ const float bz = _b.z;
+ const float bw = _b.w;
+
+ return
+ {
+ aw * bx + ax * bw + ay * bz - az * by,
+ aw * by - ax * bz + ay * bw + az * bx,
+ aw * bz + ax * by - ay * bx + az * bw,
+ aw * bw - ax * bx - ay * by - az * bz,
+ };
}
- inline float vec3Length(const float* _a)
+ inline BX_CONSTEXPR_FUNC Vec3 mul(const Vec3 _v, const Quaternion _q)
{
- return sqrt(vec3Dot(_a, _a) );
+ const Quaternion tmp0 = invert(_q);
+ const Quaternion qv = { _v.x, _v.y, _v.z, 0.0f };
+ const Quaternion tmp1 = mul(tmp0, qv);
+ const Vec3 result = mulXyz(tmp1, _q);
+
+ return result;
}
- inline float vec3Norm(float* _result, const float* _a)
+ inline BX_CONSTEXPR_FUNC float dot(const Quaternion _a, const Quaternion _b)
{
- 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;
+ return
+ _a.x * _b.x
+ + _a.y * _b.y
+ + _a.z * _b.z
+ + _a.w * _b.w
+ ;
}
- inline void vec3TangentFrame(const float* _n, float* _t, float* _b)
+ inline BX_CONSTEXPR_FUNC Quaternion normalize(const Quaternion _a)
{
- const float nx = _n[0];
- const float ny = _n[1];
- const float nz = _n[2];
-
- if (abs(nx) > abs(nz) )
- {
- float invLen = 1.0f / sqrt(nx*nx + nz*nz);
- _t[0] = -nz * invLen;
- _t[1] = 0.0f;
- _t[2] = nx * invLen;
- }
- else
+ const float norm = dot(_a, _a);
+ if (0.0f < norm)
{
- float invLen = 1.0f / sqrt(ny*ny + nz*nz);
- _t[0] = 0.0f;
- _t[1] = nz * invLen;
- _t[2] = -ny * invLen;
+ const float invNorm = rsqrt(norm);
+
+ return mul(_a, invNorm);
}
- vec3Cross(_b, _n, _t);
+ return
+ {
+ 0.0f,
+ 0.0f,
+ 0.0f,
+ 1.0f,
+ };
}
- inline void vec3TangentFrame(const float* _n, float* _t, float* _b, float _angle)
+ inline BX_CONSTEXPR_FUNC Quaternion lerp(const Quaternion _a, const Quaternion _b, float _t)
{
- vec3TangentFrame(_n, _t, _b);
-
- const float sa = sin(_angle);
- const float ca = cos(_angle);
+ const float sa = 1.0f - _t;
+ const float adotb = dot(_a, _b);
+ const float sb = sign(adotb) * _t;
- _t[0] = -sa * _b[0] + ca * _t[0];
- _t[1] = -sa * _b[1] + ca * _t[1];
- _t[2] = -sa * _b[2] + ca * _t[2];
+ const Quaternion aa = mul(_a, sa);
+ const Quaternion bb = mul(_b, sb);
+ const Quaternion qq = add(aa, bb);
- vec3Cross(_b, _n, _t);
+ return normalize(qq);
}
- inline void vec3FromLatLong(float* _vec, float _u, float _v)
+ inline BX_CONST_FUNC Quaternion fromEuler(const Vec3 _euler)
{
- const float phi = _u * kPi2;
- const float theta = _v * kPi;
-
- const float st = sin(theta);
- const float sp = sin(phi);
- const float ct = cos(theta);
- const float cp = cos(phi);
+ const float sx = sin(_euler.x * 0.5f);
+ const float cx = cos(_euler.x * 0.5f);
+ const float sy = sin(_euler.y * 0.5f);
+ const float cy = cos(_euler.y * 0.5f);
+ const float sz = sin(_euler.z * 0.5f);
+ const float cz = cos(_euler.z * 0.5f);
- _vec[0] = -st*sp;
- _vec[1] = ct;
- _vec[2] = -st*cp;
+ return
+ {
+ sx * cy * cz - cx * sy * sz,
+ cx * sy * cz + sx * cy * sz,
+ cx * cy * sz - sx * sy * cz,
+ cx * cy * cz + sx * sy * sz,
+ };
}
- inline void vec3ToLatLong(float* _outU, float* _outV, const float* _dir)
+ inline BX_CONST_FUNC Vec3 toEuler(const Quaternion _a)
{
- const float phi = atan2(_dir[0], _dir[2]);
- const float theta = acos(_dir[1]);
+ const float xx = _a.x;
+ const float yy = _a.y;
+ const float zz = _a.z;
+ const float ww = _a.w;
+ const float xsq = square(xx);
+ const float ysq = square(yy);
+ const float zsq = square(zz);
- *_outU = (bx::kPi + phi)/bx::kPi2;
- *_outV = theta*bx::kInvPi;
+ return
+ {
+ atan2(2.0f * (xx * ww - yy * zz), 1.0f - 2.0f * (xsq + zsq) ),
+ atan2(2.0f * (yy * ww + xx * zz), 1.0f - 2.0f * (ysq + zsq) ),
+ asin( 2.0f * (xx * yy + zz * ww) ),
+ };
}
- inline void quatIdentity(float* _result)
+ inline BX_CONST_FUNC Vec3 toXAxis(const Quaternion _a)
{
- _result[0] = 0.0f;
- _result[1] = 0.0f;
- _result[2] = 0.0f;
- _result[3] = 1.0f;
- }
+ const float xx = _a.x;
+ const float yy = _a.y;
+ const float zz = _a.z;
+ const float ww = _a.w;
+ const float ysq = square(yy);
+ const float zsq = square(zz);
- inline void quatMove(float* _result, const float* _a)
- {
- _result[0] = _a[0];
- _result[1] = _a[1];
- _result[2] = _a[2];
- _result[3] = _a[3];
+ return
+ {
+ 1.0f - 2.0f * ysq - 2.0f * zsq,
+ 2.0f * xx * yy + 2.0f * zz * ww,
+ 2.0f * xx * zz - 2.0f * yy * ww,
+ };
}
- inline void quatMulXYZ(float* _result, const float* _qa, const float* _qb)
+ inline BX_CONST_FUNC Vec3 toYAxis(const Quaternion _a)
{
- const float ax = _qa[0];
- const float ay = _qa[1];
- const float az = _qa[2];
- const float aw = _qa[3];
+ const float xx = _a.x;
+ const float yy = _a.y;
+ const float zz = _a.z;
+ const float ww = _a.w;
+ const float xsq = square(xx);
+ const float zsq = square(zz);
- 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;
+ return
+ {
+ 2.0f * xx * yy - 2.0f * zz * ww,
+ 1.0f - 2.0f * xsq - 2.0f * zsq,
+ 2.0f * yy * zz + 2.0f * xx * ww,
+ };
}
- inline void quatMul(float* _result, const float* _qa, const float* _qb)
+ inline BX_CONST_FUNC Vec3 toZAxis(const Quaternion _a)
{
- 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];
+ const float xx = _a.x;
+ const float yy = _a.y;
+ const float zz = _a.z;
+ const float ww = _a.w;
+ const float xsq = square(xx);
+ const float ysq = square(yy);
- _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* _result, const float* _quat)
- {
- _result[0] = -_quat[0];
- _result[1] = -_quat[1];
- _result[2] = -_quat[2];
- _result[3] = _quat[3];
+ return
+ {
+ 2.0f * xx * zz + 2.0f * yy * ww,
+ 2.0f * yy * zz - 2.0f * xx * ww,
+ 1.0f - 2.0f * xsq - 2.0f * ysq,
+ };
}
- inline float quatDot(const float* _a, const float* _b)
+ inline BX_CONST_FUNC Quaternion fromAxisAngle(const Vec3 _axis, float _angle)
{
- return _a[0]*_b[0]
- + _a[1]*_b[1]
- + _a[2]*_b[2]
- + _a[3]*_b[3]
- ;
- }
+ const float ha = _angle * 0.5f;
+ const float sa = sin(ha);
- inline void quatNorm(float* _result, const float* _quat)
- {
- const float norm = quatDot(_quat, _quat);
- if (0.0f < norm)
- {
- const float invNorm = 1.0f / sqrt(norm);
- _result[0] = _quat[0] * invNorm;
- _result[1] = _quat[1] * invNorm;
- _result[2] = _quat[2] * invNorm;
- _result[3] = _quat[3] * invNorm;
- }
- else
+ return
{
- quatIdentity(_result);
- }
+ _axis.x * sa,
+ _axis.y * sa,
+ _axis.z * sa,
+ cos(ha),
+ };
}
- inline void quatToEuler(float* _result, const float* _quat)
+ inline void toAxisAngle(Vec3& _outAxis, float& _outAngle, const Quaternion _a)
{
- const float x = _quat[0];
- const float y = _quat[1];
- const float z = _quat[2];
- const float w = _quat[3];
+ const float ww = _a.w;
+ const float sa = sqrt(1.0f - square(ww) );
- const float yy = y * y;
- const float zz = z * z;
+ _outAngle = 2.0f * acos(ww);
- const float xx = x * x;
- _result[0] = atan2(2.0f * (x * w - y * z), 1.0f - 2.0f * (xx + zz) );
- _result[1] = atan2(2.0f * (y * w + x * z), 1.0f - 2.0f * (yy + zz) );
- _result[2] = asin (2.0f * (x * y + z * w) );
- }
+ if (0.001f > sa)
+ {
+ _outAxis = { _a.x, _a.y, _a.z };
+ return;
+ }
- inline void quatRotateAxis(float* _result, const float* _axis, float _angle)
- {
- const float ha = _angle * 0.5f;
- const float ca = cos(ha);
- const float sa = sin(ha);
- _result[0] = _axis[0] * sa;
- _result[1] = _axis[1] * sa;
- _result[2] = _axis[2] * sa;
- _result[3] = ca;
+ const float invSa = 1.0f/sa;
+
+ _outAxis = { _a.x * invSa, _a.y * invSa, _a.z * invSa };
}
- inline void quatRotateX(float* _result, float _ax)
+ inline BX_CONST_FUNC Quaternion rotateX(float _ax)
{
const float hx = _ax * 0.5f;
- const float cx = cos(hx);
- const float sx = sin(hx);
- _result[0] = sx;
- _result[1] = 0.0f;
- _result[2] = 0.0f;
- _result[3] = cx;
+
+ return
+ {
+ sin(hx),
+ 0.0f,
+ 0.0f,
+ cos(hx),
+ };
}
- inline void quatRotateY(float* _result, float _ay)
+ inline BX_CONST_FUNC Quaternion rotateY(float _ay)
{
const float hy = _ay * 0.5f;
- const float cy = cos(hy);
- const float sy = sin(hy);
- _result[0] = 0.0f;
- _result[1] = sy;
- _result[2] = 0.0f;
- _result[3] = cy;
+
+ return
+ {
+ 0.0f,
+ sin(hy),
+ 0.0f,
+ cos(hy),
+ };
}
- inline void quatRotateZ(float* _result, float _az)
+ inline BX_CONST_FUNC Quaternion rotateZ(float _az)
{
const float hz = _az * 0.5f;
- const float cz = cos(hz);
- const float sz = sin(hz);
- _result[0] = 0.0f;
- _result[1] = 0.0f;
- _result[2] = sz;
- _result[3] = cz;
+
+ return
+ {
+ 0.0f,
+ 0.0f,
+ sin(hz),
+ cos(hz),
+ };
}
- inline void vec3MulQuat(float* _result, const float* _vec, const float* _quat)
+ inline BX_CONSTEXPR_FUNC bool isEqual(const Quaternion _a, const Quaternion _b, float _epsilon)
{
- 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);
+ return isEqual(_a.x, _b.x, _epsilon)
+ && isEqual(_a.y, _b.y, _epsilon)
+ && isEqual(_a.z, _b.z, _epsilon)
+ && isEqual(_a.w, _b.w, _epsilon)
+ ;
}
inline void mtxIdentity(float* _result)
@@ -883,63 +1101,63 @@ namespace bx
mtxScale(_result, _scale, _scale, _scale);
}
- inline void mtxFromNormal(float* _result, const float* _normal, float _scale, const float* _pos)
+ inline void mtxFromNormal(float* _result, const Vec3& _normal, float _scale, const Vec3& _pos)
{
- float tangent[3];
- float bitangent[3];
- vec3TangentFrame(_normal, tangent, bitangent);
+ Vec3 tangent(init::None);
+ Vec3 bitangent(init::None);
+ calcTangentFrame(tangent, bitangent, _normal);
- vec3Mul(&_result[ 0], bitangent, _scale);
- vec3Mul(&_result[ 4], _normal, _scale);
- vec3Mul(&_result[ 8], tangent, _scale);
+ store(&_result[ 0], mul(bitangent, _scale) );
+ store(&_result[ 4], mul(_normal, _scale) );
+ store(&_result[ 8], mul(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[12] = _pos.x;
+ _result[13] = _pos.y;
+ _result[14] = _pos.z;
_result[15] = 1.0f;
}
- inline void mtxFromNormal(float* _result, const float* _normal, float _scale, const float* _pos, float _angle)
+ inline void mtxFromNormal(float* _result, const Vec3& _normal, float _scale, const Vec3& _pos, float _angle)
{
- float tangent[3];
- float bitangent[3];
- vec3TangentFrame(_normal, tangent, bitangent, _angle);
+ Vec3 tangent(init::None);
+ Vec3 bitangent(init::None);
+ calcTangentFrame(tangent, bitangent, _normal, _angle);
- vec3Mul(&_result[ 0], bitangent, _scale);
- vec3Mul(&_result[ 4], _normal, _scale);
- vec3Mul(&_result[ 8], tangent, _scale);
+ store(&_result[0], mul(bitangent, _scale) );
+ store(&_result[4], mul(_normal, _scale) );
+ store(&_result[8], mul(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[12] = _pos.x;
+ _result[13] = _pos.y;
+ _result[14] = _pos.z;
_result[15] = 1.0f;
}
- inline void mtxQuat(float* _result, const float* _quat)
+ inline void mtxFromQuaternion(float* _result, const Quaternion& _rotation)
{
- const float x = _quat[0];
- const float y = _quat[1];
- const float z = _quat[2];
- const float w = _quat[3];
+ const float qx = _rotation.x;
+ const float qy = _rotation.y;
+ const float qz = _rotation.z;
+ const float qw = _rotation.w;
- 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;
+ const float x2 = qx + qx;
+ const float y2 = qy + qy;
+ const float z2 = qz + qz;
+ const float x2x = x2 * qx;
+ const float x2y = x2 * qy;
+ const float x2z = x2 * qz;
+ const float x2w = x2 * qw;
+ const float y2y = y2 * qy;
+ const float y2z = y2 * qz;
+ const float y2w = y2 * qw;
+ const float z2z = z2 * qz;
+ const float z2w = z2 * qw;
_result[ 0] = 1.0f - (y2y + z2z);
_result[ 1] = x2y - z2w;
@@ -962,27 +1180,15 @@ namespace bx
_result[15] = 1.0f;
}
- inline void mtxQuatTranslation(float* _result, const float* _quat, const float* _translation)
+ inline void mtxFromQuaternion(float* _result, const Quaternion& _rotation, const Vec3& _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* _result, const float* _quat, const float* _translation)
- {
- float quat[4];
- quat[0] = -_quat[0];
- quat[1] = -_quat[1];
- quat[2] = _quat[2];
- quat[3] = _quat[3];
- mtxQuatTranslation(_result, quat, _translation);
+ mtxFromQuaternion(_result, _rotation);
+ store(&_result[12], neg(mulXyz0(_translation, _result) ) );
}
inline Vec3 mul(const Vec3& _vec, const float* _mat)
{
- Vec3 result;
+ Vec3 result(init::None);
result.x = _vec.x * _mat[0] + _vec.y * _mat[4] + _vec.z * _mat[ 8] + _mat[12];
result.y = _vec.x * _mat[1] + _vec.y * _mat[5] + _vec.z * _mat[ 9] + _mat[13];
result.z = _vec.x * _mat[2] + _vec.y * _mat[6] + _vec.z * _mat[10] + _mat[14];
@@ -991,7 +1197,7 @@ namespace bx
inline Vec3 mulXyz0(const Vec3& _vec, const float* _mat)
{
- Vec3 result;
+ Vec3 result(init::None);
result.x = _vec.x * _mat[0] + _vec.y * _mat[4] + _vec.z * _mat[ 8];
result.y = _vec.x * _mat[1] + _vec.y * _mat[5] + _vec.z * _mat[ 9];
result.z = _vec.x * _mat[2] + _vec.y * _mat[6] + _vec.z * _mat[10];
@@ -1016,48 +1222,6 @@ namespace bx
return result;
}
- inline void vec3MulMtx(float* _result, const float* _vec, const float* _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 vec3MulMtxXyz0(float* _result, const float* _vec, const float* _mat)
- {
- _result[0] = _vec[0] * _mat[ 0] + _vec[1] * _mat[4] + _vec[2] * _mat[ 8];
- _result[1] = _vec[0] * _mat[ 1] + _vec[1] * _mat[5] + _vec[2] * _mat[ 9];
- _result[2] = _vec[0] * _mat[ 2] + _vec[1] * _mat[6] + _vec[2] * _mat[10];
- }
-
- inline void vec3MulMtxH(float* _result, const float* _vec, const float* _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 = sign(ww)/ww;
- _result[0] = xx*invW;
- _result[1] = yy*invW;
- _result[2] = zz*invW;
- }
-
- inline void vec4Mul(float* _result, const float* _a, const float* _b)
- {
- _result[0] = _a[0] * _b[0];
- _result[1] = _a[1] * _b[1];
- _result[2] = _a[2] * _b[2];
- _result[3] = _a[3] * _b[3];
- }
-
- inline void vec4Mul(float* _result, const float* _a, float _b)
- {
- _result[0] = _a[0] * _b;
- _result[1] = _a[1] * _b;
- _result[2] = _a[2] * _b;
- _result[3] = _a[3] * _b;
- }
-
inline void vec4MulMtx(float* _result, const float* _vec, const float* _mat)
{
_result[0] = _vec[0] * _mat[ 0] + _vec[1] * _mat[4] + _vec[2] * _mat[ 8] + _vec[3] * _mat[12];
@@ -1094,75 +1258,37 @@ namespace bx
_result[15] = _a[15];
}
- /// Convert LH to RH projection matrix and vice versa.
- inline void mtxProjFlipHandedness(float* _dst, const float* _src)
+ inline Vec3 calcNormal(const Vec3& _va, const Vec3& _vb, const Vec3& _vc)
{
- _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];
+ const Vec3 ba = sub(_vb, _va);
+ const Vec3 ca = sub(_vc, _va);
+ const Vec3 baxca = cross(ba, ca);
+
+ return normalize(baxca);
}
- /// Convert LH to RH view matrix and vice versa.
- inline void mtxViewFlipHandedness(float* _dst, const float* _src)
+ inline void calcPlane(Plane& _outPlane, const Vec3& _va, const Vec3& _vb, const Vec3& _vc)
{
- _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];
+ Vec3 normal = calcNormal(_va, _vb, _vc);
+ calcPlane(_outPlane, normal, _va);
}
- inline void calcNormal(float _result[3], const float _va[3], const float _vb[3], const float _vc[3])
+ inline void calcPlane(Plane& _outPlane, const Vec3& _normal, const Vec3& _pos)
{
- float ba[3];
- vec3Sub(ba, _vb, _va);
-
- float ca[3];
- vec3Sub(ca, _vc, _va);
-
- float baxca[3];
- vec3Cross(baxca, ba, ca);
-
- vec3Norm(_result, baxca);
+ _outPlane.normal = _normal;
+ _outPlane.dist = -dot(_normal, _pos);
}
- inline void calcPlane(float _result[4], const float _va[3], const float _vb[3], const float _vc[3])
+ inline BX_CONSTEXPR_FUNC float distance(const Plane& _plane, const Vec3& _pos)
{
- float normal[3];
- calcNormal(normal, _va, _vb, _vc);
- calcPlane(_result, normal, _va);
+ return dot(_plane.normal, _pos) + _plane.dist;
}
- inline void calcPlane(float _result[4], const float _normal[3], const float _pos[3])
+ inline BX_CONSTEXPR_FUNC bool isEqual(const Plane& _a, const Plane& _b, float _epsilon)
{
- _result[0] = _normal[0];
- _result[1] = _normal[1];
- _result[2] = _normal[2];
- _result[3] = -vec3Dot(_normal, _pos);
+ return isEqual(_a.normal, _b.normal, _epsilon)
+ && isEqual(_a.dist, _b.dist, _epsilon)
+ ;
}
inline BX_CONST_FUNC float toLinear(float _a)
diff --git a/3rdparty/bx/include/bx/inline/mpscqueue.inl b/3rdparty/bx/include/bx/inline/mpscqueue.inl
index a22cf283815..72747b1bfba 100644
--- a/3rdparty/bx/include/bx/inline/mpscqueue.inl
+++ b/3rdparty/bx/include/bx/inline/mpscqueue.inl
@@ -1,6 +1,6 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_MPSCQUEUE_H_HEADER_GUARD
diff --git a/3rdparty/bx/include/bx/inline/mutex.inl b/3rdparty/bx/include/bx/inline/mutex.inl
index 971ebcaa6a8..007317ebccd 100644
--- a/3rdparty/bx/include/bx/inline/mutex.inl
+++ b/3rdparty/bx/include/bx/inline/mutex.inl
@@ -1,6 +1,6 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_MUTEX_H_HEADER_GUARD
diff --git a/3rdparty/bx/include/bx/inline/os.inl b/3rdparty/bx/include/bx/inline/os.inl
new file mode 100644
index 00000000000..736b1fc83e1
--- /dev/null
+++ b/3rdparty/bx/include/bx/inline/os.inl
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
+ */
+
+#ifndef BX_H_HEADER_GUARD
+# error "Must be included from bx/os.h!"
+#endif // BX_H_HEADER_GUARD
+
+namespace bx
+{
+ template<typename ProtoT>
+ inline ProtoT dlsym(void* _handle, const StringView& _symbol)
+ {
+ return reinterpret_cast<ProtoT>(dlsym(_handle, _symbol) );
+ }
+
+} // namespace bx
diff --git a/3rdparty/bx/include/bx/inline/pixelformat.inl b/3rdparty/bx/include/bx/inline/pixelformat.inl
index 8ac02813521..0c6a334b4da 100644
--- a/3rdparty/bx/include/bx/inline/pixelformat.inl
+++ b/3rdparty/bx/include/bx/inline/pixelformat.inl
@@ -1,6 +1,6 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_PIXEL_FORMAT_H_HEADER_GUARD
@@ -31,6 +31,23 @@ namespace bx
return max(-1.0f, float(_value) / _scale);
}
+ // A8
+ inline void packA8(void* _dst, const float* _src)
+ {
+ uint8_t* dst = (uint8_t*)_dst;
+ dst[0] = uint8_t(toUnorm(_src[3], 255.0f) );
+ }
+
+ inline void unpackA8(float* _dst, const void* _src)
+ {
+ const uint8_t* src = (const uint8_t*)_src;
+ const float aa = fromUnorm(src[0], 255.0f);
+ _dst[0] = aa;
+ _dst[1] = aa;
+ _dst[2] = aa;
+ _dst[3] = aa;
+ }
+
// R8
inline void packR8(void* _dst, const float* _src)
{
@@ -806,8 +823,8 @@ namespace bx
memCopy(_dst, _src, 16);
}
- // R5G6B5
- inline void packR5G6B5(void* _dst, const float* _src)
+ // B5G6R5
+ inline void packB5G6R5(void* _dst, const float* _src)
{
*( (uint16_t*)_dst) = 0
| uint16_t(toUnorm(_src[0], 31.0f)<<11)
@@ -816,7 +833,7 @@ namespace bx
;
}
- inline void unpackR5G6B5(float* _dst, const void* _src)
+ inline void unpackB5G6R5(float* _dst, const void* _src)
{
uint16_t packed = *( (const uint16_t*)_src);
_dst[0] = float( ( (packed>>11) & 0x1f) ) / 31.0f;
@@ -825,6 +842,25 @@ namespace bx
_dst[3] = 1.0f;
}
+ // R5G6B5
+ inline void packR5G6B5(void* _dst, const float* _src)
+ {
+ *( (uint16_t*)_dst) = 0
+ | uint16_t(toUnorm(_src[0], 31.0f) )
+ | uint16_t(toUnorm(_src[1], 63.0f)<< 5)
+ | uint16_t(toUnorm(_src[2], 31.0f)<<11)
+ ;
+ }
+
+ inline void unpackR5G6B5(float* _dst, const void* _src)
+ {
+ uint16_t packed = *( (const uint16_t*)_src);
+ _dst[0] = float( ( (packed ) & 0x1f) ) / 31.0f;
+ _dst[1] = float( ( (packed>> 5) & 0x3f) ) / 63.0f;
+ _dst[2] = float( ( (packed>>11) & 0x1f) ) / 31.0f;
+ _dst[3] = 1.0f;
+ }
+
// RGBA4
inline void packRgba4(void* _dst, const float* _src)
{
@@ -845,7 +881,7 @@ namespace bx
_dst[3] = float( ( (packed>>12) & 0xf) ) / 15.0f;
}
- // RGBA4
+ // BGRA4
inline void packBgra4(void* _dst, const float* _src)
{
*( (uint16_t*)_dst) = 0
@@ -882,7 +918,7 @@ namespace bx
_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) );
+ _dst[3] = float( ( (packed>>15) & 0x1) );
}
// BGR5A1
@@ -902,7 +938,7 @@ namespace bx
_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) );
+ _dst[3] = float( ( (packed>>15) & 0x1) );
}
// RGB10A2
@@ -930,8 +966,8 @@ namespace bx
{
*( (uint32_t*)_dst) = 0
| ( (halfFromFloat(_src[0])>> 4) & 0x7ff)
- | ( (halfFromFloat(_src[0])<< 7) & 0x3ff800)
- | ( (halfFromFloat(_src[0])<<17) & 0xffc00000)
+ | ( (halfFromFloat(_src[1])<< 7) & 0x3ff800)
+ | ( (halfFromFloat(_src[2])<<17) & 0xffc00000)
;
}
diff --git a/3rdparty/bx/include/bx/inline/readerwriter.inl b/3rdparty/bx/include/bx/inline/readerwriter.inl
index 9a365dcee60..fa9300b7a2d 100644
--- a/3rdparty/bx/include/bx/inline/readerwriter.inl
+++ b/3rdparty/bx/include/bx/inline/readerwriter.inl
@@ -1,6 +1,6 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_READERWRITER_H_HEADER_GUARD
@@ -118,7 +118,7 @@ namespace bx
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.");
+ BX_ASSERT(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
int32_t morecore = int32_t(m_pos - m_top) + _size;
@@ -132,7 +132,7 @@ namespace bx
m_pos += size;
if (size != _size)
{
- BX_ERROR_SET(_err, BX_ERROR_READERWRITER_WRITE, "SizerWriter: write truncated.");
+ BX_ERROR_SET(_err, kErrorReaderWriterWrite, "SizerWriter: write truncated.");
}
return size;
}
@@ -170,7 +170,7 @@ namespace bx
inline int32_t MemoryReader::read(void* _data, int32_t _size, Error* _err)
{
- BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
+ BX_ASSERT(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(min<int64_t>(remainder, INT32_MAX) ) );
@@ -178,7 +178,7 @@ namespace bx
m_pos += size;
if (size != _size)
{
- BX_ERROR_SET(_err, BX_ERROR_READERWRITER_READ, "MemoryReader: read truncated.");
+ BX_ERROR_SET(_err, kErrorReaderWriterRead, "MemoryReader: read truncated.");
}
return size;
}
@@ -233,13 +233,13 @@ namespace bx
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.");
+ BX_ASSERT(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);
+ morecore = alignUp(morecore, 0x1000);
m_data = (uint8_t*)m_memBlock->more(morecore);
m_size = m_memBlock->getSize();
}
@@ -251,7 +251,7 @@ namespace bx
m_top = max(m_top, m_pos);
if (size != _size)
{
- BX_ERROR_SET(_err, BX_ERROR_READERWRITER_WRITE, "MemoryWriter: write truncated.");
+ BX_ERROR_SET(_err, kErrorReaderWriterWrite, "MemoryWriter: write truncated.");
}
return size;
}
@@ -273,7 +273,7 @@ namespace bx
}
template<typename Ty>
- int32_t read(ReaderI* _reader, Ty& _value, Error* _err)
+ inline int32_t read(ReaderI* _reader, Ty& _value, Error* _err)
{
BX_ERROR_SCOPE(_err);
BX_STATIC_ASSERT(isTriviallyCopyable<Ty>() );
@@ -281,7 +281,7 @@ namespace bx
}
template<typename Ty>
- int32_t readHE(ReaderI* _reader, Ty& _value, bool _fromLittleEndian, Error* _err)
+ inline int32_t readHE(ReaderI* _reader, Ty& _value, bool _fromLittleEndian, Error* _err)
{
BX_ERROR_SCOPE(_err);
BX_STATIC_ASSERT(isTriviallyCopyable<Ty>() );
@@ -329,7 +329,7 @@ namespace bx
}
template<typename Ty>
- int32_t write(WriterI* _writer, const Ty& _value, Error* _err)
+ inline int32_t write(WriterI* _writer, const Ty& _value, Error* _err)
{
BX_ERROR_SCOPE(_err);
BX_STATIC_ASSERT(isTriviallyCopyable<Ty>() );
@@ -337,7 +337,7 @@ namespace bx
}
template<typename Ty>
- int32_t writeLE(WriterI* _writer, const Ty& _value, Error* _err)
+ inline int32_t writeLE(WriterI* _writer, const Ty& _value, Error* _err)
{
BX_ERROR_SCOPE(_err);
BX_STATIC_ASSERT(isTriviallyCopyable<Ty>() );
@@ -346,8 +346,14 @@ namespace bx
return result;
}
+ template<>
+ inline int32_t writeLE(WriterI* _writer, const float& _value, Error* _err)
+ {
+ return writeLE(_writer, floatToBits(_value), _err);
+ }
+
template<typename Ty>
- int32_t writeBE(WriterI* _writer, const Ty& _value, Error* _err)
+ inline int32_t writeBE(WriterI* _writer, const Ty& _value, Error* _err)
{
BX_ERROR_SCOPE(_err);
BX_STATIC_ASSERT(isTriviallyCopyable<Ty>() );
@@ -356,6 +362,12 @@ namespace bx
return result;
}
+ template<>
+ inline int32_t writeBE(WriterI* _writer, const float& _value, Error* _err)
+ {
+ return writeBE(_writer, floatToBits(_value), _err);
+ }
+
inline int64_t skip(SeekerI* _seeker, int64_t _offset)
{
return _seeker->seek(_offset, Whence::Current);
@@ -392,7 +404,7 @@ namespace bx
}
template<typename Ty>
- int32_t peek(ReaderSeekerI* _reader, Ty& _value, Error* _err)
+ inline int32_t peek(ReaderSeekerI* _reader, Ty& _value, Error* _err)
{
BX_ERROR_SCOPE(_err);
BX_STATIC_ASSERT(isTriviallyCopyable<Ty>() );
@@ -410,7 +422,7 @@ namespace bx
const int64_t offset = bx::seek(_reader, size);
if (offset != aligned)
{
- BX_ERROR_SET(_err, BX_ERROR_READERWRITER_WRITE, "Align: read truncated.");
+ BX_ERROR_SET(_err, kErrorReaderWriterWrite, "Align: read truncated.");
}
return int32_t(offset - current);
}
diff --git a/3rdparty/bx/include/bx/inline/ringbuffer.inl b/3rdparty/bx/include/bx/inline/ringbuffer.inl
index 51f365546db..1c1b7ec44d0 100644
--- a/3rdparty/bx/include/bx/inline/ringbuffer.inl
+++ b/3rdparty/bx/include/bx/inline/ringbuffer.inl
@@ -1,6 +1,6 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_RINGBUFFER_H_HEADER_GUARD
@@ -161,7 +161,7 @@ namespace bx
, m_size(_size)
, m_buffer(_buffer)
{
- BX_CHECK(_control.available() >= _size, "%d >= %d", _control.available(), _size);
+ BX_ASSERT(_control.available() >= _size, "%d >= %d", _control.available(), _size);
}
template <typename ControlT>
@@ -210,7 +210,7 @@ namespace bx
{
uint32_t size = m_control.reserve(_size);
BX_UNUSED(size);
- BX_CHECK(size == _size, "%d == %d", size, _size);
+ BX_ASSERT(size == _size, "%d == %d", size, _size);
m_write = m_control.m_current;
m_end = m_write+_size;
}
diff --git a/3rdparty/bx/include/bx/inline/rng.inl b/3rdparty/bx/include/bx/inline/rng.inl
index 9577bb09aa9..123461ddf7d 100644
--- a/3rdparty/bx/include/bx/inline/rng.inl
+++ b/3rdparty/bx/include/bx/inline/rng.inl
@@ -1,6 +1,6 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_RNG_H_HEADER_GUARD
@@ -103,6 +103,10 @@ namespace bx
inline void generateSphereHammersley(void* _data, uint32_t _stride, uint32_t _num, float _scale)
{
+ // Reference(s):
+ // - Sampling with Hammersley and Halton Points
+ // https://web.archive.org/web/20190207230709/http://www.cse.cuhk.edu.hk/~ttwong/papers/udpoint/udpoints.html
+
uint8_t* data = (uint8_t*)_data;
for (uint32_t ii = 0; ii < _num; ii++)
@@ -133,7 +137,7 @@ namespace bx
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!");
+ BX_ASSERT(_num != 0, "Number of elements can't be 0!");
for (uint32_t ii = 0, num = _num-1; ii < num; ++ii)
{
diff --git a/3rdparty/bx/include/bx/inline/simd128_langext.inl b/3rdparty/bx/include/bx/inline/simd128_langext.inl
index ac08ba7f9de..6b94e6125af 100644
--- a/3rdparty/bx/include/bx/inline/simd128_langext.inl
+++ b/3rdparty/bx/include/bx/inline/simd128_langext.inl
@@ -1,6 +1,6 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_SIMD_T_H_HEADER_GUARD
@@ -347,6 +347,14 @@ BX_SIMD128_IMPLEMENT_TEST(xyzw , 0xf);
}
template<>
+ BX_SIMD_FORCE_INLINE simd128_langext_t simd_cmpneq(simd128_langext_t _a, simd128_langext_t _b)
+ {
+ simd128_langext_t result;
+ result.vi = _a.vf != _b.vf;
+ return result;
+ }
+
+ template<>
BX_SIMD_FORCE_INLINE simd128_langext_t simd_cmplt(simd128_langext_t _a, simd128_langext_t _b)
{
simd128_langext_t result;
diff --git a/3rdparty/bx/include/bx/inline/simd128_neon.inl b/3rdparty/bx/include/bx/inline/simd128_neon.inl
index 95107eeaa27..0ba98920da7 100644
--- a/3rdparty/bx/include/bx/inline/simd128_neon.inl
+++ b/3rdparty/bx/include/bx/inline/simd128_neon.inl
@@ -1,6 +1,6 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_SIMD_T_H_HEADER_GUARD
@@ -9,6 +9,15 @@
namespace bx
{
+
+#if BX_COMPILER_CLANG
+# define SHUFFLE_A(_a, _i0, _i1, _i2, _i3) __builtin_shufflevector(_a, _a, _i0, _i1, _i2, _i3 )
+# define SHUFFLE_AB(_a, _b, _i0, _i1, _i2, _i3) __builtin_shufflevector(_a, _b, _i0, _i1, _i2, _i3 )
+#else
+# define SHUFFLE_A(_a, _i0, _i1, _i2, _i3) __builtin_shuffle(_a, (uint32x4_t){ _i0, _i1, _i2, _i3 })
+# define SHUFFLE_AB(_a, _b, _i0, _i1, _i2, _i3) __builtin_shuffle(_a, _b, (uint32x4_t){ _i0, _i1, _i2, _i3 })
+#endif
+
#define ELEMx 0
#define ELEMy 1
#define ELEMz 2
@@ -17,7 +26,7 @@ namespace bx
template<> \
BX_SIMD_FORCE_INLINE simd128_neon_t simd_swiz_##_x##_y##_z##_w(simd128_neon_t _a) \
{ \
- return __builtin_shuffle(_a, (uint32x4_t){ ELEM##_x, ELEM##_y, ELEM##_z, ELEM##_w }); \
+ return SHUFFLE_A(_a, ELEM##_x, ELEM##_y, ELEM##_z, ELEM##_w ); \
}
#include "simd128_swizzle.inl"
@@ -74,50 +83,52 @@ BX_SIMD128_IMPLEMENT_TEST(yzw, yzww);
template<>
BX_SIMD_FORCE_INLINE simd128_neon_t simd_shuf_xyAB(simd128_neon_t _a, simd128_neon_t _b)
{
- return __builtin_shuffle(_a, _b, (uint32x4_t){ 0, 1, 4, 5 });
+ return SHUFFLE_AB(_a, _b, 0, 1, 4, 5 );
}
template<>
BX_SIMD_FORCE_INLINE simd128_neon_t simd_shuf_ABxy(simd128_neon_t _a, simd128_neon_t _b)
{
- return __builtin_shuffle(_a, _b, (uint32x4_t){ 4, 5, 0, 1 });
+ return SHUFFLE_AB(_a, _b, 4, 5, 0, 1 );
}
template<>
BX_SIMD_FORCE_INLINE simd128_neon_t simd_shuf_CDzw(simd128_neon_t _a, simd128_neon_t _b)
{
- return __builtin_shuffle(_a, _b, (uint32x4_t){ 6, 7, 2, 3 });
+ return SHUFFLE_AB(_a, _b, 6, 7, 2, 3 );
}
template<>
BX_SIMD_FORCE_INLINE simd128_neon_t simd_shuf_zwCD(simd128_neon_t _a, simd128_neon_t _b)
{
- return __builtin_shuffle(_a, _b, (uint32x4_t){ 2, 3, 6, 7 });
+ return SHUFFLE_AB(_a, _b, 2, 3, 6, 7 );
}
template<>
BX_SIMD_FORCE_INLINE simd128_neon_t simd_shuf_xAyB(simd128_neon_t _a, simd128_neon_t _b)
{
- return __builtin_shuffle(_a, _b, (uint32x4_t){ 0, 4, 1, 5 });
+ return SHUFFLE_AB(_a, _b, 0, 4, 1, 5 );
}
template<>
BX_SIMD_FORCE_INLINE simd128_neon_t simd_shuf_AxBy(simd128_neon_t _a, simd128_neon_t _b)
{
- return __builtin_shuffle(_a, _b, (uint32x4_t){ 1, 5, 0, 4 });
+ return SHUFFLE_AB(_a, _b, 4, 0, 5, 1 );
}
template<>
BX_SIMD_FORCE_INLINE simd128_neon_t simd_shuf_zCwD(simd128_neon_t _a, simd128_neon_t _b)
{
- return __builtin_shuffle(_a, _b, (uint32x4_t){ 2, 6, 3, 7 });
+ return SHUFFLE_AB(_a, _b, 2, 6, 3, 7 );
}
template<>
BX_SIMD_FORCE_INLINE simd128_neon_t simd_shuf_CzDw(simd128_neon_t _a, simd128_neon_t _b)
{
- return __builtin_shuffle(_a, _b, (uint32x4_t){ 6, 2, 7, 3 });
+ return SHUFFLE_AB(_a, _b, 6, 2, 7, 3 );
}
+#undef SHUFFLE_A
+#undef SHUFFLE_AB
template<>
BX_SIMD_FORCE_INLINE float simd_x(simd128_neon_t _a)
@@ -273,10 +284,16 @@ BX_SIMD128_IMPLEMENT_TEST(yzw, yzww);
}
template<>
+ BX_SIMD_FORCE_INLINE simd128_neon_t simd_cmpneq(simd128_neon_t _a, simd128_neon_t _b)
+ {
+ return simd_cmpneq_ni(_a, _b);
+ }
+
+ template<>
BX_SIMD_FORCE_INLINE simd128_neon_t simd_cmplt(simd128_neon_t _a, simd128_neon_t _b)
{
- const uint32x4_t tmp = vcltq_f32(_a, _b);
- const simd128_neon_t result = vreinterpretq_f32_u32(tmp);
+ const uint32x4_t tmp = vcltq_f32(_a, _b);
+ const simd128_neon_t result = vreinterpretq_f32_u32(tmp);
return result;
}
@@ -284,8 +301,8 @@ BX_SIMD128_IMPLEMENT_TEST(yzw, yzww);
template<>
BX_SIMD_FORCE_INLINE simd128_neon_t simd_cmple(simd128_neon_t _a, simd128_neon_t _b)
{
- const uint32x4_t tmp = vcleq_f32(_a, _b);
- const simd128_neon_t result = vreinterpretq_f32_u32(tmp);
+ const uint32x4_t tmp = vcleq_f32(_a, _b);
+ const simd128_neon_t result = vreinterpretq_f32_u32(tmp);
return result;
}
@@ -293,8 +310,8 @@ BX_SIMD128_IMPLEMENT_TEST(yzw, yzww);
template<>
BX_SIMD_FORCE_INLINE simd128_neon_t simd_cmpgt(simd128_neon_t _a, simd128_neon_t _b)
{
- const uint32x4_t tmp = vcgtq_f32(_a, _b);
- const simd128_neon_t result = vreinterpretq_f32_u32(tmp);
+ const uint32x4_t tmp = vcgtq_f32(_a, _b);
+ const simd128_neon_t result = vreinterpretq_f32_u32(tmp);
return result;
}
@@ -302,8 +319,8 @@ BX_SIMD128_IMPLEMENT_TEST(yzw, yzww);
template<>
BX_SIMD_FORCE_INLINE simd128_neon_t simd_cmpge(simd128_neon_t _a, simd128_neon_t _b)
{
- const uint32x4_t tmp = vcgeq_f32(_a, _b);
- const simd128_neon_t result = vreinterpretq_f32_u32(tmp);
+ const uint32x4_t tmp = vcgeq_f32(_a, _b);
+ const simd128_neon_t result = vreinterpretq_f32_u32(tmp);
return result;
}
@@ -367,6 +384,7 @@ BX_SIMD128_IMPLEMENT_TEST(yzw, yzww);
template<>
BX_SIMD_FORCE_INLINE simd128_neon_t simd_sll(simd128_neon_t _a, int _count)
{
+#if !BX_COMPILER_CLANG
if (__builtin_constant_p(_count) )
{
const uint32x4_t tmp0 = vreinterpretq_u32_f32(_a);
@@ -375,7 +393,7 @@ BX_SIMD128_IMPLEMENT_TEST(yzw, yzww);
return result;
}
-
+#endif
const uint32x4_t tmp0 = vreinterpretq_u32_f32(_a);
const int32x4_t shift = vdupq_n_s32(_count);
const uint32x4_t tmp1 = vshlq_u32(tmp0, shift);
@@ -387,6 +405,7 @@ BX_SIMD128_IMPLEMENT_TEST(yzw, yzww);
template<>
BX_SIMD_FORCE_INLINE simd128_neon_t simd_srl(simd128_neon_t _a, int _count)
{
+#if !BX_COMPILER_CLANG
if (__builtin_constant_p(_count) )
{
const uint32x4_t tmp0 = vreinterpretq_u32_f32(_a);
@@ -395,7 +414,7 @@ BX_SIMD128_IMPLEMENT_TEST(yzw, yzww);
return result;
}
-
+#endif
const uint32x4_t tmp0 = vreinterpretq_u32_f32(_a);
const int32x4_t shift = vdupq_n_s32(-_count);
const uint32x4_t tmp1 = vshlq_u32(tmp0, shift);
@@ -407,6 +426,7 @@ BX_SIMD128_IMPLEMENT_TEST(yzw, yzww);
template<>
BX_SIMD_FORCE_INLINE simd128_neon_t simd_sra(simd128_neon_t _a, int _count)
{
+#if !BX_COMPILER_CLANG
if (__builtin_constant_p(_count) )
{
const int32x4_t tmp0 = vreinterpretq_s32_f32(_a);
@@ -415,7 +435,7 @@ BX_SIMD128_IMPLEMENT_TEST(yzw, yzww);
return result;
}
-
+#endif
const int32x4_t tmp0 = vreinterpretq_s32_f32(_a);
const int32x4_t shift = vdupq_n_s32(-_count);
const int32x4_t tmp1 = vshlq_s32(tmp0, shift);
diff --git a/3rdparty/bx/include/bx/inline/simd128_ref.inl b/3rdparty/bx/include/bx/inline/simd128_ref.inl
index 6895b24f46a..b0a97b0e627 100644
--- a/3rdparty/bx/include/bx/inline/simd128_ref.inl
+++ b/3rdparty/bx/include/bx/inline/simd128_ref.inl
@@ -1,6 +1,6 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_SIMD_T_H_HEADER_GUARD
@@ -59,21 +59,21 @@ namespace bx
return (_mask) == (tmp&(_mask) ); \
}
-BX_SIMD128_IMPLEMENT_TEST(x , 0x1);
-BX_SIMD128_IMPLEMENT_TEST(y , 0x2);
-BX_SIMD128_IMPLEMENT_TEST(xy , 0x3);
-BX_SIMD128_IMPLEMENT_TEST(z , 0x4);
-BX_SIMD128_IMPLEMENT_TEST(xz , 0x5);
-BX_SIMD128_IMPLEMENT_TEST(yz , 0x6);
-BX_SIMD128_IMPLEMENT_TEST(xyz , 0x7);
-BX_SIMD128_IMPLEMENT_TEST(w , 0x8);
-BX_SIMD128_IMPLEMENT_TEST(xw , 0x9);
-BX_SIMD128_IMPLEMENT_TEST(yw , 0xa);
-BX_SIMD128_IMPLEMENT_TEST(xyw , 0xb);
-BX_SIMD128_IMPLEMENT_TEST(zw , 0xc);
-BX_SIMD128_IMPLEMENT_TEST(xzw , 0xd);
-BX_SIMD128_IMPLEMENT_TEST(yzw , 0xe);
-BX_SIMD128_IMPLEMENT_TEST(xyzw , 0xf);
+BX_SIMD128_IMPLEMENT_TEST(x , 0x1)
+BX_SIMD128_IMPLEMENT_TEST(y , 0x2)
+BX_SIMD128_IMPLEMENT_TEST(xy , 0x3)
+BX_SIMD128_IMPLEMENT_TEST(z , 0x4)
+BX_SIMD128_IMPLEMENT_TEST(xz , 0x5)
+BX_SIMD128_IMPLEMENT_TEST(yz , 0x6)
+BX_SIMD128_IMPLEMENT_TEST(xyz , 0x7)
+BX_SIMD128_IMPLEMENT_TEST(w , 0x8)
+BX_SIMD128_IMPLEMENT_TEST(xw , 0x9)
+BX_SIMD128_IMPLEMENT_TEST(yw , 0xa)
+BX_SIMD128_IMPLEMENT_TEST(xyw , 0xb)
+BX_SIMD128_IMPLEMENT_TEST(zw , 0xc)
+BX_SIMD128_IMPLEMENT_TEST(xzw , 0xd)
+BX_SIMD128_IMPLEMENT_TEST(yzw , 0xe)
+BX_SIMD128_IMPLEMENT_TEST(xyzw , 0xf)
#undef BX_SIMD128_IMPLEMENT_TEST
@@ -136,10 +136,10 @@ BX_SIMD128_IMPLEMENT_TEST(xyzw , 0xf);
BX_SIMD_FORCE_INLINE simd128_ref_t simd_shuf_AxBy(simd128_ref_t _a, simd128_ref_t _b)
{
simd128_ref_t result;
- result.uxyzw[0] = _a.uxyzw[1];
- result.uxyzw[1] = _b.uxyzw[1];
- result.uxyzw[2] = _a.uxyzw[0];
- result.uxyzw[3] = _b.uxyzw[0];
+ result.uxyzw[0] = _b.uxyzw[0];
+ result.uxyzw[1] = _a.uxyzw[0];
+ result.uxyzw[2] = _b.uxyzw[1];
+ result.uxyzw[3] = _a.uxyzw[1];
return result;
}
@@ -397,6 +397,17 @@ BX_SIMD128_IMPLEMENT_TEST(xyzw , 0xf);
}
template<>
+ BX_SIMD_FORCE_INLINE simd128_ref_t simd_cmpneq(simd128_ref_t _a, simd128_ref_t _b)
+ {
+ simd128_ref_t result;
+ result.ixyzw[0] = _a.fxyzw[0] != _b.fxyzw[0] ? 0xffffffff : 0x0;
+ result.ixyzw[1] = _a.fxyzw[1] != _b.fxyzw[1] ? 0xffffffff : 0x0;
+ result.ixyzw[2] = _a.fxyzw[2] != _b.fxyzw[2] ? 0xffffffff : 0x0;
+ result.ixyzw[3] = _a.fxyzw[3] != _b.fxyzw[3] ? 0xffffffff : 0x0;
+ return result;
+ }
+
+ template<>
BX_SIMD_FORCE_INLINE simd128_ref_t simd_cmplt(simd128_ref_t _a, simd128_ref_t _b)
{
simd128_ref_t result;
diff --git a/3rdparty/bx/include/bx/inline/simd128_sse.inl b/3rdparty/bx/include/bx/inline/simd128_sse.inl
index 229c1431fe3..c8c2a475e34 100644
--- a/3rdparty/bx/include/bx/inline/simd128_sse.inl
+++ b/3rdparty/bx/include/bx/inline/simd128_sse.inl
@@ -1,6 +1,6 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_SIMD_T_H_HEADER_GUARD
@@ -41,21 +41,21 @@ namespace bx
return (_mask) == (_mm_movemask_ps(_test)&(_mask) ); \
}
-BX_SIMD128_IMPLEMENT_TEST(x , 0x1);
-BX_SIMD128_IMPLEMENT_TEST(y , 0x2);
-BX_SIMD128_IMPLEMENT_TEST(xy , 0x3);
-BX_SIMD128_IMPLEMENT_TEST(z , 0x4);
-BX_SIMD128_IMPLEMENT_TEST(xz , 0x5);
-BX_SIMD128_IMPLEMENT_TEST(yz , 0x6);
-BX_SIMD128_IMPLEMENT_TEST(xyz , 0x7);
-BX_SIMD128_IMPLEMENT_TEST(w , 0x8);
-BX_SIMD128_IMPLEMENT_TEST(xw , 0x9);
-BX_SIMD128_IMPLEMENT_TEST(yw , 0xa);
-BX_SIMD128_IMPLEMENT_TEST(xyw , 0xb);
-BX_SIMD128_IMPLEMENT_TEST(zw , 0xc);
-BX_SIMD128_IMPLEMENT_TEST(xzw , 0xd);
-BX_SIMD128_IMPLEMENT_TEST(yzw , 0xe);
-BX_SIMD128_IMPLEMENT_TEST(xyzw , 0xf);
+BX_SIMD128_IMPLEMENT_TEST(x , 0x1)
+BX_SIMD128_IMPLEMENT_TEST(y , 0x2)
+BX_SIMD128_IMPLEMENT_TEST(xy , 0x3)
+BX_SIMD128_IMPLEMENT_TEST(z , 0x4)
+BX_SIMD128_IMPLEMENT_TEST(xz , 0x5)
+BX_SIMD128_IMPLEMENT_TEST(yz , 0x6)
+BX_SIMD128_IMPLEMENT_TEST(xyz , 0x7)
+BX_SIMD128_IMPLEMENT_TEST(w , 0x8)
+BX_SIMD128_IMPLEMENT_TEST(xw , 0x9)
+BX_SIMD128_IMPLEMENT_TEST(yw , 0xa)
+BX_SIMD128_IMPLEMENT_TEST(xyw , 0xb)
+BX_SIMD128_IMPLEMENT_TEST(zw , 0xc)
+BX_SIMD128_IMPLEMENT_TEST(xzw , 0xd)
+BX_SIMD128_IMPLEMENT_TEST(yzw , 0xe)
+BX_SIMD128_IMPLEMENT_TEST(xyzw , 0xf)
#undef BX_SIMD128_IMPLEMENT_TEST
@@ -309,6 +309,12 @@ BX_SIMD128_IMPLEMENT_TEST(xyzw , 0xf);
}
template<>
+ BX_SIMD_FORCE_INLINE simd128_sse_t simd_cmpneq(simd128_sse_t _a, simd128_sse_t _b)
+ {
+ return _mm_cmpneq_ps(_a, _b);
+ }
+
+ template<>
BX_SIMD_FORCE_INLINE simd128_sse_t simd_cmplt(simd128_sse_t _a, simd128_sse_t _b)
{
return _mm_cmplt_ps(_a, _b);
diff --git a/3rdparty/bx/include/bx/inline/simd128_swizzle.inl b/3rdparty/bx/include/bx/inline/simd128_swizzle.inl
index b1ff9a0d183..34ac39b7e57 100644
--- a/3rdparty/bx/include/bx/inline/simd128_swizzle.inl
+++ b/3rdparty/bx/include/bx/inline/simd128_swizzle.inl
@@ -1,6 +1,6 @@
/*
* Copyright 2010-2015 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_SIMD_T_H_HEADER_GUARD
diff --git a/3rdparty/bx/include/bx/inline/simd256_avx.inl b/3rdparty/bx/include/bx/inline/simd256_avx.inl
index 4dd9c666f71..1dce947c79b 100644
--- a/3rdparty/bx/include/bx/inline/simd256_avx.inl
+++ b/3rdparty/bx/include/bx/inline/simd256_avx.inl
@@ -1,6 +1,6 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_SIMD_T_H_HEADER_GUARD
diff --git a/3rdparty/bx/include/bx/inline/simd256_ref.inl b/3rdparty/bx/include/bx/inline/simd256_ref.inl
index 0c84d9d82a0..f27204780b3 100644
--- a/3rdparty/bx/include/bx/inline/simd256_ref.inl
+++ b/3rdparty/bx/include/bx/inline/simd256_ref.inl
@@ -1,6 +1,6 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_SIMD_T_H_HEADER_GUARD
diff --git a/3rdparty/bx/include/bx/inline/simd_ni.inl b/3rdparty/bx/include/bx/inline/simd_ni.inl
index eb388513e88..579bb0bc21f 100644
--- a/3rdparty/bx/include/bx/inline/simd_ni.inl
+++ b/3rdparty/bx/include/bx/inline/simd_ni.inl
@@ -1,6 +1,6 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
namespace bx
@@ -125,6 +125,15 @@ namespace bx
}
template<typename Ty>
+ BX_SIMD_INLINE Ty simd_cmpneq_ni(Ty _a, Ty _b)
+ {
+ const Ty tmp0 = simd_cmpeq(_a, _b);
+ const Ty result = simd_not(tmp0);
+
+ return result;
+ }
+
+ template<typename Ty>
BX_SIMD_INLINE Ty simd_min_ni(Ty _a, Ty _b)
{
const Ty mask = simd_cmplt(_a, _b);
diff --git a/3rdparty/bx/include/bx/inline/sort.inl b/3rdparty/bx/include/bx/inline/sort.inl
index 27a085362da..ed72c3a3293 100644
--- a/3rdparty/bx/include/bx/inline/sort.inl
+++ b/3rdparty/bx/include/bx/inline/sort.inl
@@ -1,6 +1,6 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_SORT_H_HEADER_GUARD
@@ -9,21 +9,127 @@
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)
+ template<typename Ty>
+ inline int32_t compareAscending(const void* _lhs, const void* _rhs)
+ {
+ const Ty lhs = *static_cast<const Ty*>(_lhs);
+ const Ty rhs = *static_cast<const Ty*>(_rhs);
+ return (lhs > rhs) - (lhs < rhs);
+ }
+
+ template<typename Ty>
+ inline int32_t compareDescending(const void* _lhs, const void* _rhs)
+ {
+ return compareAscending<Ty>(_rhs, _lhs);
+ }
+
+ template<>
+ inline int32_t compareAscending<const char*>(const void* _lhs, const void* _rhs)
+ {
+ return strCmp(*(const char**)_lhs, *(const char**)_rhs);
+ }
+
+ template<>
+ inline int32_t compareAscending<StringView>(const void* _lhs, const void* _rhs)
+ {
+ return strCmp(*(const StringView*)_lhs, *(const StringView*)_rhs);
+ }
+
+ template<typename Ty>
+ inline void quickSort(void* _data, uint32_t _num, uint32_t _stride, const ComparisonFn _fn)
+ {
+ BX_STATIC_ASSERT(isTriviallyMoveAssignable<Ty>(), "Element type must be trivially move assignable");
+ quickSort(_data, _num, _stride, _fn);
+ }
+
+ template<typename Ty>
+ inline void quickSort(Ty* _data, uint32_t _num, const ComparisonFn _fn)
+ {
+ BX_STATIC_ASSERT(isTriviallyMoveAssignable<Ty>(), "Element type must be trivially move assignable");
+ quickSort( (void*)_data, _num, sizeof(Ty), _fn);
+ }
+
+ template<typename Ty>
+ inline uint32_t unique(void* _data, uint32_t _num, uint32_t _stride, const ComparisonFn _fn)
+ {
+ BX_STATIC_ASSERT(isTriviallyMoveAssignable<Ty>(), "Element type must be trivially move assignable");
+ return unique(_data, _num, _stride, _fn);
+ }
+
+ template<typename Ty>
+ inline uint32_t unique(Ty* _data, uint32_t _num, const ComparisonFn _fn)
+ {
+ BX_STATIC_ASSERT(isTriviallyMoveAssignable<Ty>(), "Element type must be trivially move assignable");
+ return unique( (void*)_data, _num, sizeof(Ty), _fn);
+ }
+
+ template<typename Ty>
+ inline uint32_t lowerBound(const Ty& _key, const Ty* _data, uint32_t _num, const ComparisonFn _fn)
+ {
+ return lowerBound( (const void*)&_key, _data, _num, sizeof(Ty), _fn);
+ }
+
+ template<typename Ty>
+ inline uint32_t lowerBound(const Ty& _key, const void* _data, uint32_t _num, uint32_t _stride, const ComparisonFn _fn)
+ {
+ return lowerBound( (const void*)&_key, _data, _num, _stride, _fn);
+ }
+
+ template<typename Ty>
+ inline uint32_t upperBound(const Ty& _key, const Ty* _data, uint32_t _num, const ComparisonFn _fn)
+ {
+ return upperBound( (const void*)&_key, _data, _num, sizeof(Ty), _fn);
+ }
+
+ template<typename Ty>
+ inline uint32_t upperBound(const Ty& _key, const void* _data, uint32_t _num, uint32_t _stride, const ComparisonFn _fn)
+ {
+ return upperBound( (const void*)&_key, _data, _num, _stride, _fn);
+ }
+
+ template<typename Ty>
+ inline bool isSorted(const Ty* _data, uint32_t _num, const ComparisonFn _fn)
+ {
+ return isSorted(_data, _num, sizeof(Ty), _fn);
+ }
+
+ template<typename Ty>
+ inline bool isSorted(const void* _data, uint32_t _num, uint32_t _stride, const ComparisonFn _fn)
+ {
+ return isSorted(_data, _num, _stride, _fn);
+ }
+
+ template<typename Ty>
+ inline int32_t binarySearch(const Ty& _key, const Ty* _data, uint32_t _num, const ComparisonFn _fn)
+ {
+ return binarySearch( (const void*)&_key, _data, _num, sizeof(Ty), _fn);
+ }
+
+ template<typename Ty>
+ inline int32_t binarySearch(const Ty& _key, const void* _data, uint32_t _num, uint32_t _stride, const ComparisonFn _fn)
+ {
+ return binarySearch( (const void*)&_key, _data, _num, _stride, _fn);
+ }
+
+ namespace radix_sort_detail
+ {
+ constexpr uint32_t kBits = 11;
+ constexpr uint32_t kHistogramSize = 1<<kBits;
+ constexpr uint32_t kBitMask = kHistogramSize-1;
+
+ } // namespace radix_sort_detail
inline void radixSort(uint32_t* _keys, uint32_t* _tempKeys, uint32_t _size)
{
uint32_t* keys = _keys;
uint32_t* tempKeys = _tempKeys;
- uint32_t histogram[BX_RADIXSORT_HISTOGRAM_SIZE];
+ uint32_t histogram[radix_sort_detail::kHistogramSize];
uint16_t shift = 0;
uint32_t pass = 0;
for (; pass < 3; ++pass)
{
- memSet(histogram, 0, sizeof(uint32_t)*BX_RADIXSORT_HISTOGRAM_SIZE);
+ memSet(histogram, 0, sizeof(uint32_t)*radix_sort_detail::kHistogramSize);
bool sorted = true;
{
@@ -32,7 +138,7 @@ namespace bx
for (uint32_t ii = 0; ii < _size; ++ii, prevKey = key)
{
key = keys[ii];
- uint16_t index = (key>>shift)&BX_RADIXSORT_BIT_MASK;
+ uint16_t index = (key>>shift)&radix_sort_detail::kBitMask;
++histogram[index];
sorted &= prevKey <= key;
}
@@ -44,7 +150,7 @@ namespace bx
}
uint32_t offset = 0;
- for (uint32_t ii = 0; ii < BX_RADIXSORT_HISTOGRAM_SIZE; ++ii)
+ for (uint32_t ii = 0; ii < radix_sort_detail::kHistogramSize; ++ii)
{
uint32_t count = histogram[ii];
histogram[ii] = offset;
@@ -54,7 +160,7 @@ namespace bx
for (uint32_t ii = 0; ii < _size; ++ii)
{
uint32_t key = keys[ii];
- uint16_t index = (key>>shift)&BX_RADIXSORT_BIT_MASK;
+ uint16_t index = (key>>shift)&radix_sort_detail::kBitMask;
uint32_t dest = histogram[index]++;
tempKeys[dest] = key;
}
@@ -63,7 +169,7 @@ namespace bx
tempKeys = keys;
keys = swapKeys;
- shift += BX_RADIXSORT_BITS;
+ shift += radix_sort_detail::kBits;
}
done:
@@ -77,17 +183,19 @@ done:
template <typename Ty>
inline void radixSort(uint32_t* _keys, uint32_t* _tempKeys, Ty* _values, Ty* _tempValues, uint32_t _size)
{
+ BX_STATIC_ASSERT(isTriviallyMoveAssignable<Ty>(), "Sort element type must be trivially move assignable");
+
uint32_t* keys = _keys;
uint32_t* tempKeys = _tempKeys;
Ty* values = _values;
Ty* tempValues = _tempValues;
- uint32_t histogram[BX_RADIXSORT_HISTOGRAM_SIZE];
+ uint32_t histogram[radix_sort_detail::kHistogramSize];
uint16_t shift = 0;
uint32_t pass = 0;
for (; pass < 3; ++pass)
{
- memSet(histogram, 0, sizeof(uint32_t)*BX_RADIXSORT_HISTOGRAM_SIZE);
+ memSet(histogram, 0, sizeof(uint32_t)*radix_sort_detail::kHistogramSize);
bool sorted = true;
{
@@ -96,7 +204,7 @@ done:
for (uint32_t ii = 0; ii < _size; ++ii, prevKey = key)
{
key = keys[ii];
- uint16_t index = (key>>shift)&BX_RADIXSORT_BIT_MASK;
+ uint16_t index = (key>>shift)&radix_sort_detail::kBitMask;
++histogram[index];
sorted &= prevKey <= key;
}
@@ -108,7 +216,7 @@ done:
}
uint32_t offset = 0;
- for (uint32_t ii = 0; ii < BX_RADIXSORT_HISTOGRAM_SIZE; ++ii)
+ for (uint32_t ii = 0; ii < radix_sort_detail::kHistogramSize; ++ii)
{
uint32_t count = histogram[ii];
histogram[ii] = offset;
@@ -118,7 +226,7 @@ done:
for (uint32_t ii = 0; ii < _size; ++ii)
{
uint32_t key = keys[ii];
- uint16_t index = (key>>shift)&BX_RADIXSORT_BIT_MASK;
+ uint16_t index = (key>>shift)&radix_sort_detail::kBitMask;
uint32_t dest = histogram[index]++;
tempKeys[dest] = key;
tempValues[dest] = values[ii];
@@ -132,7 +240,7 @@ done:
tempValues = values;
values = swapValues;
- shift += BX_RADIXSORT_BITS;
+ shift += radix_sort_detail::kBits;
}
done:
@@ -152,12 +260,12 @@ done:
uint64_t* keys = _keys;
uint64_t* tempKeys = _tempKeys;
- uint32_t histogram[BX_RADIXSORT_HISTOGRAM_SIZE];
+ uint32_t histogram[radix_sort_detail::kHistogramSize];
uint16_t shift = 0;
uint32_t pass = 0;
for (; pass < 6; ++pass)
{
- memSet(histogram, 0, sizeof(uint32_t)*BX_RADIXSORT_HISTOGRAM_SIZE);
+ memSet(histogram, 0, sizeof(uint32_t)*radix_sort_detail::kHistogramSize);
bool sorted = true;
{
@@ -166,7 +274,7 @@ done:
for (uint32_t ii = 0; ii < _size; ++ii, prevKey = key)
{
key = keys[ii];
- uint16_t index = (key>>shift)&BX_RADIXSORT_BIT_MASK;
+ uint16_t index = (key>>shift)&radix_sort_detail::kBitMask;
++histogram[index];
sorted &= prevKey <= key;
}
@@ -178,7 +286,7 @@ done:
}
uint32_t offset = 0;
- for (uint32_t ii = 0; ii < BX_RADIXSORT_HISTOGRAM_SIZE; ++ii)
+ for (uint32_t ii = 0; ii < radix_sort_detail::kHistogramSize; ++ii)
{
uint32_t count = histogram[ii];
histogram[ii] = offset;
@@ -188,7 +296,7 @@ done:
for (uint32_t ii = 0; ii < _size; ++ii)
{
uint64_t key = keys[ii];
- uint16_t index = (key>>shift)&BX_RADIXSORT_BIT_MASK;
+ uint16_t index = (key>>shift)&radix_sort_detail::kBitMask;
uint32_t dest = histogram[index]++;
tempKeys[dest] = key;
}
@@ -197,7 +305,7 @@ done:
tempKeys = keys;
keys = swapKeys;
- shift += BX_RADIXSORT_BITS;
+ shift += radix_sort_detail::kBits;
}
done:
@@ -211,17 +319,19 @@ done:
template <typename Ty>
inline void radixSort(uint64_t* _keys, uint64_t* _tempKeys, Ty* _values, Ty* _tempValues, uint32_t _size)
{
+ BX_STATIC_ASSERT(isTriviallyMoveAssignable<Ty>(), "Sort element type must be trivially move assignable");
+
uint64_t* keys = _keys;
uint64_t* tempKeys = _tempKeys;
Ty* values = _values;
Ty* tempValues = _tempValues;
- uint32_t histogram[BX_RADIXSORT_HISTOGRAM_SIZE];
+ uint32_t histogram[radix_sort_detail::kHistogramSize];
uint16_t shift = 0;
uint32_t pass = 0;
for (; pass < 6; ++pass)
{
- memSet(histogram, 0, sizeof(uint32_t)*BX_RADIXSORT_HISTOGRAM_SIZE);
+ memSet(histogram, 0, sizeof(uint32_t)*radix_sort_detail::kHistogramSize);
bool sorted = true;
{
@@ -230,7 +340,7 @@ done:
for (uint32_t ii = 0; ii < _size; ++ii, prevKey = key)
{
key = keys[ii];
- uint16_t index = (key>>shift)&BX_RADIXSORT_BIT_MASK;
+ uint16_t index = (key>>shift)&radix_sort_detail::kBitMask;
++histogram[index];
sorted &= prevKey <= key;
}
@@ -242,7 +352,7 @@ done:
}
uint32_t offset = 0;
- for (uint32_t ii = 0; ii < BX_RADIXSORT_HISTOGRAM_SIZE; ++ii)
+ for (uint32_t ii = 0; ii < radix_sort_detail::kHistogramSize; ++ii)
{
uint32_t count = histogram[ii];
histogram[ii] = offset;
@@ -252,7 +362,7 @@ done:
for (uint32_t ii = 0; ii < _size; ++ii)
{
uint64_t key = keys[ii];
- uint16_t index = (key>>shift)&BX_RADIXSORT_BIT_MASK;
+ uint16_t index = (key>>shift)&radix_sort_detail::kBitMask;
uint32_t dest = histogram[index]++;
tempKeys[dest] = key;
tempValues[dest] = values[ii];
@@ -266,7 +376,7 @@ done:
tempValues = values;
values = swapValues;
- shift += BX_RADIXSORT_BITS;
+ shift += radix_sort_detail::kBits;
}
done:
@@ -281,8 +391,4 @@ done:
}
}
-#undef BX_RADIXSORT_BITS
-#undef BX_RADIXSORT_HISTOGRAM_SIZE
-#undef BX_RADIXSORT_BIT_MASK
-
} // namespace bx
diff --git a/3rdparty/bx/include/bx/inline/spscqueue.inl b/3rdparty/bx/include/bx/inline/spscqueue.inl
index e0fae02ef29..9db8b748d70 100644
--- a/3rdparty/bx/include/bx/inline/spscqueue.inl
+++ b/3rdparty/bx/include/bx/inline/spscqueue.inl
@@ -1,6 +1,6 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_SPSCQUEUE_H_HEADER_GUARD
@@ -9,7 +9,10 @@
namespace bx
{
- // http://drdobbs.com/article/print?articleId=210604448&siteSectionName=
+ // Reference(s):
+ // - Writing Lock-Free Code: A Corrected Queue
+ // https://web.archive.org/web/20190207230604/http://www.drdobbs.com/parallel/writing-lock-free-code-a-corrected-queue/210604448
+ //
inline SpScUnboundedQueue::SpScUnboundedQueue(AllocatorI* _allocator)
: m_allocator(_allocator)
, m_first(BX_NEW(m_allocator, Node)(NULL) )
diff --git a/3rdparty/bx/include/bx/inline/string.inl b/3rdparty/bx/include/bx/inline/string.inl
index a387128679e..a696f342ff3 100644
--- a/3rdparty/bx/include/bx/inline/string.inl
+++ b/3rdparty/bx/include/bx/inline/string.inl
@@ -1,6 +1,6 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_STRING_H_HEADER_GUARD
@@ -37,22 +37,6 @@ namespace bx
va_end(argList);
}
- template <typename Ty>
- inline Ty replaceAll(const Ty& _str, const char* _from, const char* _to)
- {
- Ty str = _str;
- typename Ty::size_type startPos = 0;
- const typename Ty::size_type fromLen = strLen(_from);
- const typename Ty::size_type toLen = strLen(_to);
- while ( (startPos = str.find(_from, startPos) ) != Ty::npos)
- {
- str.replace(startPos, fromLen, _to);
- startPos += toLen;
- }
-
- return str;
- }
-
inline StringView::StringView()
{
clear();
@@ -75,21 +59,11 @@ namespace bx
return *this;
}
- inline StringView::StringView(char* _ptr)
- {
- set(_ptr, INT32_MAX);
- }
-
inline StringView::StringView(const char* _ptr)
{
set(_ptr, INT32_MAX);
}
- inline StringView::StringView(char* _ptr, int32_t _len)
- {
- set(_ptr, _len);
- }
-
inline StringView::StringView(const char* _ptr, int32_t _len)
{
set(_ptr, _len);
@@ -100,17 +74,6 @@ namespace bx
set(_ptr, _term);
}
- template<typename Ty>
- inline StringView::StringView(const Ty& _container)
- {
- set(_container);
- }
-
- inline void StringView::set(char* _ptr)
- {
- set(_ptr, INT32_MAX);
- }
-
inline void StringView::set(const char* _ptr)
{
set(_ptr, INT32_MAX);
@@ -124,6 +87,7 @@ namespace bx
{
m_len = INT32_MAX == _len ? strLen(_ptr) : _len;
m_ptr = _ptr;
+ m_0terminated = INT32_MAX == _len;
}
}
@@ -132,12 +96,6 @@ namespace bx
set(_ptr, int32_t(_term-_ptr) );
}
- template<typename Ty>
- inline void StringView::set(const Ty& _container)
- {
- set(_container.data(), int32_t(_container.length() ) );
- }
-
inline void StringView::set(const StringView& _str, int32_t _start, int32_t _len)
{
const int32_t start = min(_start, _str.m_len);
@@ -149,6 +107,7 @@ namespace bx
{
m_ptr = "";
m_len = 0;
+ m_0terminated = true;
}
inline const char* StringView::getPtr() const
@@ -171,36 +130,46 @@ namespace bx
return m_len;
}
+ inline bool StringView::is0Terminated() const
+ {
+ return m_0terminated;
+ }
+
template<bx::AllocatorI** AllocatorT>
inline StringT<AllocatorT>::StringT()
: StringView()
+ , m_capacity(0)
{
+ clear();
}
template<bx::AllocatorI** AllocatorT>
inline StringT<AllocatorT>::StringT(const StringT<AllocatorT>& _rhs)
: StringView()
+ , m_capacity(0)
{
set(_rhs);
}
template<bx::AllocatorI** AllocatorT>
- inline StringT<AllocatorT>& StringT<AllocatorT>::operator=(const StringT<AllocatorT>& _rhs)
+ inline StringT<AllocatorT>::StringT(const StringView& _rhs)
+ : StringView()
+ , m_capacity(0)
{
set(_rhs);
- return *this;
}
template<bx::AllocatorI** AllocatorT>
- inline StringT<AllocatorT>::StringT(const StringView& _rhs)
+ inline StringT<AllocatorT>::~StringT()
{
- set(_rhs);
+ clear();
}
template<bx::AllocatorI** AllocatorT>
- inline StringT<AllocatorT>::~StringT()
+ inline StringT<AllocatorT>& StringT<AllocatorT>::operator=(const StringT<AllocatorT>& _rhs)
{
- clear();
+ set(_rhs);
+ return *this;
}
template<bx::AllocatorI** AllocatorT>
@@ -215,30 +184,129 @@ namespace bx
{
if (0 != _str.getLength() )
{
- int32_t old = m_len;
- int32_t len = m_len + strLen(_str);
- char* ptr = (char*)BX_REALLOC(*AllocatorT, 0 != m_len ? const_cast<char*>(m_ptr) : NULL, len+1);
+ const int32_t old = m_len;
+ const int32_t len = m_len + _str.getLength();
+
+ char* ptr = const_cast<char*>(m_ptr);
+
+ if (len+1 > m_capacity)
+ {
+ const int32_t capacity = alignUp(len+1, 256);
+ ptr = (char*)BX_REALLOC(*AllocatorT, 0 != m_capacity ? ptr : NULL, capacity);
+
+ *const_cast<char**>(&m_ptr) = ptr;
+ m_capacity = capacity;
+ }
+
m_len = len;
strCopy(ptr + old, len-old+1, _str);
-
- *const_cast<char**>(&m_ptr) = ptr;
}
}
template<bx::AllocatorI** AllocatorT>
+ inline void StringT<AllocatorT>::append(const char* _ptr, const char* _term)
+ {
+ append(StringView(_ptr, _term) );
+ }
+
+ template<bx::AllocatorI** AllocatorT>
inline void StringT<AllocatorT>::clear()
{
- if (0 != m_len)
+ m_0terminated = true;
+
+ if (0 != m_capacity)
{
BX_FREE(*AllocatorT, const_cast<char*>(m_ptr) );
StringView::clear();
+ m_capacity = 0;
}
}
+ template<bx::AllocatorI** AllocatorT>
+ inline const char* StringT<AllocatorT>::getCPtr() const
+ {
+ return getPtr();
+ }
+
inline StringView strSubstr(const StringView& _str, int32_t _start, int32_t _len)
{
return StringView(_str, _start, _len);
}
+ inline LineReader::LineReader(const bx::StringView& _str)
+ : m_str(_str)
+ {
+ reset();
+ }
+
+ inline void LineReader::reset()
+ {
+ m_curr = m_str;
+ m_line = 0;
+ }
+
+ inline StringView LineReader::next()
+ {
+ if (m_curr.getPtr() != m_str.getTerm() )
+ {
+ ++m_line;
+
+ StringView curr(m_curr);
+ m_curr = bx::strFindNl(m_curr);
+
+ StringView line(curr.getPtr(), m_curr.getPtr() );
+
+ return strRTrim(strRTrim(line, "\n"), "\r");
+ }
+
+ return m_curr;
+ }
+
+ inline bool LineReader::isDone() const
+ {
+ return m_curr.getPtr() == m_str.getTerm();
+ }
+
+ inline uint32_t LineReader::getLine() const
+ {
+ return m_line;
+ }
+
+ inline bool hasPrefix(const StringView& _str, const StringView& _prefix)
+ {
+ const int32_t len = _prefix.getLength();
+ return _str.getLength() >= len
+ && 0 == strCmp(_str, _prefix, len)
+ ;
+ }
+
+ inline bool hasSuffix(const StringView& _str, const StringView& _suffix)
+ {
+ const int32_t len = _suffix.getLength();
+ return _str.getLength() >= len
+ && 0 == strCmp(StringView(_str.getTerm() - len, _str.getTerm() ), _suffix, len)
+ ;
+ }
+
+ inline StringView strTrimPrefix(const StringView& _str, const StringView& _prefix)
+ {
+ if (hasPrefix(_str, _prefix) )
+ {
+ return StringView(_str.getPtr() + _prefix.getLength(), _str.getTerm() );
+ }
+
+ return _str;
+ }
+
+ inline StringView strTrimSuffix(const StringView& _str, const StringView& _suffix)
+ {
+ if (hasSuffix(_str, _suffix) )
+ {
+ return StringView(_str.getPtr(), _str.getTerm() - _suffix.getLength() );
+ }
+
+ return _str;
+ }
+
} // namespace bx
diff --git a/3rdparty/bx/include/bx/inline/typetraits.inl b/3rdparty/bx/include/bx/inline/typetraits.inl
new file mode 100644
index 00000000000..3af6a05143b
--- /dev/null
+++ b/3rdparty/bx/include/bx/inline/typetraits.inl
@@ -0,0 +1,462 @@
+/*
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
+ */
+
+#ifndef BX_TYPETRAITS_H_HEADER_GUARD
+# error "Must be included from bx/typetraits.h!"
+#endif // BX_TYPETRAITS_H_HEADER_GUARD
+
+namespace bx
+{
+ // Reference(s):
+ //
+ // - GCC type traits compiler intrisics
+ // https://gcc.gnu.org/onlinedocs/gcc-11.1.0/gcc/Type-Traits.html
+ //
+ // - Clang type trait primitives
+ // https://clang.llvm.org/docs/LanguageExtensions.html#type-trait-primitives
+
+ //---
+ template<typename Ty, Ty ValueT>
+ struct IntegralConstantT
+ {
+ using ValueType = Ty;
+ static constexpr Ty value = ValueT;
+ };
+
+ template<bool BoolT>
+ using BoolConstantT = IntegralConstantT<bool, BoolT>;
+ using FalseConstant = BoolConstantT<false>;
+ using TrueConstant = BoolConstantT<true >;
+
+ //---
+ template<typename Ty> struct TypeIdentityT { using Type = Ty; };
+ template<typename Ty> using TypeIdentityType = typename TypeIdentityT<Ty>::Type;
+
+ //---
+ template<bool BoolT, typename Ty, typename Uy> struct ConditionalT { using Type = Ty; };
+ template< typename Ty, typename Uy> struct ConditionalT<false, Ty, Uy> { using Type = Uy; };
+ template<bool BoolT, typename Ty, typename Uy> using ConditionalType = typename ConditionalT<BoolT, Ty, Uy>::Type;
+
+ //---
+ template<bool BoolT, typename Ty = void> struct EnableIfT { };
+ template< typename Ty > struct EnableIfT<true, Ty> { using Type = Ty; };
+ template<bool BoolT, typename Ty > using EnableIfType = typename EnableIfT<BoolT, Ty>::Type;
+
+ //---
+ template<typename Ty> struct AddLvalueReferenceT { using Type = Ty&; };
+ template<typename Ty> struct AddLvalueReferenceT<Ty&> { using Type = Ty&; };
+ template<> struct AddLvalueReferenceT< void> { using Type = void; };
+ template<> struct AddLvalueReferenceT<const void> { using Type = const void; };
+ template<> struct AddLvalueReferenceT<volatile void> { using Type = volatile void; };
+ template<> struct AddLvalueReferenceT<const volatile void> { using Type = const volatile void; };
+ template<typename Ty> using AddLvalueReferenceType = typename AddLvalueReferenceT<Ty>::Type;
+
+ //---
+ template<typename Ty> struct AddRvalueReferenceT { using Type = Ty&&; };
+ template<typename Ty> struct AddRvalueReferenceT<Ty&> { using Type = Ty&; };
+ template<> struct AddRvalueReferenceT< void> { using Type = void; };
+ template<> struct AddRvalueReferenceT<const void> { using Type = const void; };
+ template<> struct AddRvalueReferenceT<volatile void> { using Type = volatile void; };
+ template<> struct AddRvalueReferenceT<const volatile void> { using Type = const volatile void; };
+ template<typename Ty> using AddRvalueReferenceType = typename AddRvalueReferenceT<Ty>::Type;
+
+ //---
+ template<typename Ty> struct RemoveReferenceT { using Type = Ty; };
+ template<typename Ty> struct RemoveReferenceT<Ty&> { using Type = Ty; };
+ template<typename Ty> struct RemoveReferenceT<Ty&&> { using Type = Ty; };
+ template<typename Ty> using RemoveReferenceType = typename RemoveReferenceT<Ty>::Type;
+
+ //---
+ template<typename Ty> struct AddPointerT { using Type = TypeIdentityType<RemoveReferenceType<Ty>*>; };
+ template<typename Ty> using AddPointerType = typename AddPointerT<Ty>::Type;
+
+ //---
+ template<typename Ty> struct RemovePointerT { using Type = Ty; };
+ template<typename Ty> struct RemovePointerT< Ty* > { using Type = Ty; };
+ template<typename Ty> struct RemovePointerT< const Ty* > { using Type = Ty; };
+ template<typename Ty> struct RemovePointerT< volatile Ty* > { using Type = Ty; };
+ template<typename Ty> struct RemovePointerT<const volatile Ty* > { using Type = Ty; };
+ template<typename Ty> struct RemovePointerT<const volatile Ty* const > { using Type = Ty; };
+ template<typename Ty> struct RemovePointerT< Ty* const > { using Type = Ty; };
+ template<typename Ty> struct RemovePointerT< Ty* volatile> { using Type = Ty; };
+ template<typename Ty> struct RemovePointerT< Ty* const volatile> { using Type = Ty; };
+ template<typename Ty> using RemovePointerType = typename RemovePointerT<Ty>::Type;
+
+ //---
+ template<typename Ty> struct AddCvT { using Type = const volatile Ty; };
+ template<typename Ty> using AddCvType = typename AddCvT<Ty>::Type;
+
+ //---
+ template<typename Ty> struct RemoveCvT { using Type = Ty; };
+ template<typename Ty> struct RemoveCvT<const Ty> { using Type = Ty; };
+ template<typename Ty> struct RemoveCvT<volatile Ty> { using Type = Ty; };
+ template<typename Ty> struct RemoveCvT<const volatile Ty> { using Type = Ty; };
+ template<typename Ty> using RemoveCvType = typename RemoveCvT<Ty>::Type;
+
+ //---
+ template<typename Ty> struct AddConstT { using Type = const Ty; };
+ template<typename Ty> using AddConstType = typename AddConstT<Ty>::Type;
+
+ //---
+ template<typename Ty> struct RemoveConstT { using Type = Ty; };
+ template<typename Ty> struct RemoveConstT<const Ty> { using Type = Ty; };
+ template<typename Ty> using RemoveConstType = typename RemoveConstT<Ty>::Type;
+
+ //---
+ template<typename Ty> struct AddVolatileT { using Type = volatile Ty; };
+ template<typename Ty> using AddVolatileType = typename AddVolatileT<Ty>::Type;
+
+ //---
+ template<typename Ty> struct RemoveVolatileT { using Type = Ty; };
+ template<typename Ty> struct RemoveVolatileT<volatile Ty> { using Type = Ty; };
+ template<typename Ty> using RemoveVolatileType = typename RemoveVolatileT<Ty>::Type;
+
+ //---
+
+ template<typename Ty> struct IsBoundedArrayT : FalseConstant {};
+ template<typename Ty, size_t SizeT> struct IsBoundedArrayT<Ty[SizeT]> : TrueConstant {};
+
+ template<typename Ty>
+ inline constexpr bool isBoundedArray()
+ {
+ return IsBoundedArrayT<Ty>::value;
+ }
+
+ template<typename Ty> struct IsUnboundedArrayT : FalseConstant {};
+ template<typename Ty> struct IsUnboundedArrayT<Ty[]> : TrueConstant {};
+
+ template<typename Ty>
+ inline constexpr bool isUnboundedArray()
+ {
+ return IsUnboundedArrayT<Ty>::value;
+ }
+
+ template<typename Ty>
+ inline constexpr bool isArray()
+ {
+ return isBoundedArray<Ty>()
+ || isUnboundedArray<Ty>()
+ ;
+ }
+
+ template<typename Ty>
+ inline constexpr bool isEnum()
+ {
+ return !!__is_enum(Ty);
+ }
+
+ template<typename Ty>
+ inline constexpr bool isUnion()
+ {
+ return !!__is_union(Ty);
+ }
+
+ template<typename Ty>
+ inline constexpr bool isAbstract()
+ {
+ return !!__is_abstract(Ty);
+ }
+
+ template<typename Ty>
+ inline constexpr bool isAggregate()
+ {
+ return !!__is_aggregate(Ty);
+ }
+
+ template<typename BaseT, typename DerivedT>
+ inline constexpr bool isBaseOf()
+ {
+ return !!__is_base_of(BaseT, DerivedT);
+ }
+
+ template<typename Ty>
+ inline constexpr bool isPolymorphic()
+ {
+ return !!__is_polymorphic(Ty);
+ }
+
+ template<typename Ty>
+ inline constexpr bool isDestructorVirtual()
+ {
+ return __has_virtual_destructor(Ty);
+ }
+
+ template<typename Ty>
+ inline constexpr bool isClass()
+ {
+ return !!__is_class(Ty);
+ }
+
+ template<typename Ty>
+ inline constexpr bool isFinal()
+ {
+ return !!__is_final(Ty);
+ }
+
+ template<typename Ty>
+ inline constexpr bool isEmpty()
+ {
+ return !!__is_empty(Ty);
+ }
+
+ template<typename Ty>
+ inline constexpr bool isStandardLayout()
+ {
+ return !!__is_standard_layout(Ty);
+ }
+
+ template<typename Ty>
+ inline constexpr bool isTrivial()
+ {
+ return !!__is_trivial(Ty);
+ }
+
+ template<typename Ty>
+ inline constexpr bool isPod()
+ {
+ return isStandardLayout<Ty>()
+ && isTrivial<Ty>()
+ ;
+ }
+
+ template<typename Ty, typename FromT>
+ inline constexpr bool isAssignable()
+ {
+ return !!__is_assignable(Ty, FromT);
+ }
+
+ template<typename Ty>
+ inline constexpr bool isCopyAssignable()
+ {
+ return isAssignable<
+ AddLvalueReferenceType<Ty>
+ , AddLvalueReferenceType<const Ty>
+ >();
+ }
+
+ template<typename Ty>
+ inline constexpr bool isMoveAssignable()
+ {
+ return isAssignable<
+ AddLvalueReferenceType<Ty>
+ , AddRvalueReferenceType<Ty>
+ >();
+ }
+
+ template<typename Ty, typename FromT>
+ inline constexpr bool isTriviallyAssignable()
+ {
+ return !!__is_trivially_assignable(Ty, FromT);
+ }
+
+ template<typename Ty>
+ inline constexpr bool isTriviallyCopyAssignable()
+ {
+ return isTriviallyAssignable<
+ AddLvalueReferenceType<Ty>
+ , AddRvalueReferenceType<const Ty>
+ >();
+ }
+
+ template<typename Ty>
+ inline constexpr bool isTriviallyMoveAssignable()
+ {
+ return isTriviallyAssignable<
+ AddLvalueReferenceType<Ty>
+ , AddRvalueReferenceType<Ty>
+ >();
+ }
+
+ template<typename Ty, typename... ArgsT>
+ inline constexpr bool isConstructible()
+ {
+ return !!__is_constructible(Ty, ArgsT...);
+ }
+
+ template<typename Ty>
+ inline constexpr bool isCopyConstructible()
+ {
+ return isConstructible<Ty, AddLvalueReferenceType<Ty>>();
+ }
+
+ template<typename Ty>
+ inline constexpr bool isMoveConstructible()
+ {
+ return isConstructible<Ty, AddRvalueReferenceType<Ty>>();
+ }
+
+ template<typename Ty, typename... ArgsT>
+ inline constexpr bool isTriviallyConstructible()
+ {
+ return !!__is_trivially_constructible(Ty, ArgsT...);
+ }
+
+ template<typename Ty>
+ inline constexpr bool isTriviallyCopyConstructible()
+ {
+ return isTriviallyConstructible<Ty, AddLvalueReferenceType<Ty>>();
+ }
+
+ template<typename Ty>
+ inline constexpr bool isTriviallyMoveConstructible()
+ {
+ return isTriviallyConstructible<Ty, AddRvalueReferenceType<Ty>>();
+ }
+
+ template<typename Ty>
+ inline constexpr bool isTriviallyCopyable()
+ {
+ return !!__is_trivially_copyable(Ty);
+ }
+
+ template<typename Ty>
+ inline constexpr bool isTriviallyDestructible()
+ {
+#if BX_COMPILER_GCC
+ return !!__has_trivial_destructor(Ty);
+#else
+ return !!__is_trivially_destructible(Ty);
+#endif // BX_COMPILER_GCC
+ }
+
+ template<typename Ty> struct IsConstT : FalseConstant {};
+ template<typename Ty> struct IsConstT<const Ty> : TrueConstant {};
+
+ template<typename Ty>
+ inline constexpr bool isConst()
+ {
+ return IsConstT<Ty>::value;
+ }
+
+ template<typename Ty> struct IsVolatileT : FalseConstant {};
+ template<typename Ty> struct IsVolatileT<volatile Ty> : TrueConstant {};
+
+ template<typename Ty>
+ inline constexpr bool isVolatile()
+ {
+ return IsVolatileT<Ty>::value;
+ }
+
+ template<typename Ty> struct IsLvalueReferenceT : FalseConstant {};
+ template<typename Ty> struct IsLvalueReferenceT<Ty&> : TrueConstant {};
+
+ template<typename Ty>
+ inline constexpr bool isLvalueReference()
+ {
+ return IsLvalueReferenceT<Ty>::value;
+ }
+
+ template<typename Ty> struct IsRvalueReferenceT : FalseConstant {};
+ template<typename Ty> struct IsRvalueReferenceT<Ty&&> : TrueConstant {};
+
+ template<typename Ty>
+ inline constexpr bool isRvalueReference()
+ {
+ return IsRvalueReferenceT<Ty>::value;
+ }
+
+ template<typename Ty>
+ inline constexpr bool isReference()
+ {
+ return isLvalueReference<Ty>()
+ || isRvalueReference<Ty>()
+ ;
+ }
+
+ template<typename Ty> struct IsPointerT : FalseConstant {};
+ template<typename Ty> struct IsPointerT<Ty*> : TrueConstant {};
+ template<typename Ty> struct IsPointerT<Ty* const> : TrueConstant {};
+ template<typename Ty> struct IsPointerT<Ty* volatile> : TrueConstant {};
+ template<typename Ty> struct IsPointerT<Ty* const volatile> : TrueConstant {};
+
+ template<typename Ty>
+ inline constexpr bool isPointer()
+ {
+ return IsPointerT<Ty>::value;
+ }
+
+ template<typename Ty>
+ inline constexpr bool isSigned()
+ {
+ return Ty(-1) < Ty(0);
+ }
+
+ template<typename Ty>
+ inline constexpr bool isUnsigned()
+ {
+ return Ty(-1) > Ty(0);
+ }
+
+ template<typename Ty> struct IsIntegerT : FalseConstant {};
+ template<> struct IsIntegerT<bool > : TrueConstant {};
+ template<> struct IsIntegerT<char > : TrueConstant {};
+ template<> struct IsIntegerT<char16_t > : TrueConstant {};
+ template<> struct IsIntegerT<char32_t > : TrueConstant {};
+ template<> struct IsIntegerT<wchar_t > : TrueConstant {};
+ template<> struct IsIntegerT< signed char > : TrueConstant {};
+ template<> struct IsIntegerT<unsigned char > : TrueConstant {};
+ template<> struct IsIntegerT< short > : TrueConstant {};
+ template<> struct IsIntegerT<unsigned short > : TrueConstant {};
+ template<> struct IsIntegerT< int > : TrueConstant {};
+ template<> struct IsIntegerT<unsigned int > : TrueConstant {};
+ template<> struct IsIntegerT< long > : TrueConstant {};
+ template<> struct IsIntegerT<unsigned long > : TrueConstant {};
+ template<> struct IsIntegerT< long long> : TrueConstant {};
+ template<> struct IsIntegerT<unsigned long long> : TrueConstant {};
+
+ template<typename Ty>
+ inline constexpr bool isInteger()
+ {
+ return IsIntegerT<Ty>::value;
+ }
+
+ template<typename Ty> struct IsFloatingPointT : FalseConstant {};
+ template<> struct IsFloatingPointT<float > : TrueConstant {};
+ template<> struct IsFloatingPointT< double> : TrueConstant {};
+ template<> struct IsFloatingPointT<long double> : TrueConstant {};
+
+ template<typename Ty>
+ inline constexpr bool isFloatingPoint()
+ {
+ return IsFloatingPointT<Ty>::value;
+ }
+
+ template<typename Ty>
+ inline constexpr bool isArithmetic()
+ {
+ return isInteger<Ty>()
+ || isFloatingPoint<Ty>()
+ ;
+ }
+
+ template<typename Ty, typename Uy> struct IsSameT : FalseConstant {};
+ template<typename Ty> struct IsSameT<Ty, Ty> : TrueConstant {};
+
+ template<typename Ty, typename Uy>
+ inline constexpr bool isSame()
+ {
+ return IsSameT<Ty, Uy>::value;
+ }
+
+ template<typename Ty>
+ inline constexpr RemoveReferenceType<Ty>&& move(Ty&& _a)
+ {
+ return static_cast<RemoveReferenceType<Ty>&&>(_a);
+ }
+
+ template<typename Ty>
+ inline constexpr Ty&& forward(RemoveReferenceType<Ty>& _a)
+ {
+ return static_cast<Ty&&>(_a);
+ }
+
+ template<typename Ty>
+ inline constexpr Ty&& forward(RemoveReferenceType<Ty>&& _a)
+ {
+ BX_STATIC_ASSERT(!isLvalueReference<Ty>(), "Can not forward an Rvalue as an Lvalue.");
+ return static_cast<Ty&&>(_a);
+ }
+
+} // namespace bx
diff --git a/3rdparty/bx/include/bx/inline/uint32_t.inl b/3rdparty/bx/include/bx/inline/uint32_t.inl
index 2a17582b0db..5cd3c2103ba 100644
--- a/3rdparty/bx/include/bx/inline/uint32_t.inl
+++ b/3rdparty/bx/include/bx/inline/uint32_t.inl
@@ -1,6 +1,6 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
// Copyright 2006 Mike Acton <macton@gmail.com>
@@ -307,8 +307,12 @@ namespace bx
return result;
}
+ template<>
inline BX_CONSTEXPR_FUNC uint32_t uint32_cntbits(uint32_t _val)
{
+#if BX_COMPILER_GCC || BX_COMPILER_CLANG
+ return __builtin_popcount(_val);
+#else
const uint32_t tmp0 = uint32_srl(_val, 1);
const uint32_t tmp1 = uint32_and(tmp0, 0x55555555);
const uint32_t tmp2 = uint32_sub(_val, tmp1);
@@ -328,10 +332,43 @@ namespace bx
const uint32_t result = uint32_and(tmpF, 0x3f);
return result;
+#endif // BX_COMPILER_*
}
+ template<>
+ inline BX_CONSTEXPR_FUNC uint32_t uint32_cntbits(unsigned long long _val)
+ {
+#if BX_COMPILER_GCC || BX_COMPILER_CLANG
+ return __builtin_popcountll(_val);
+#else
+ const uint32_t lo = uint32_t(_val&UINT32_MAX);
+ const uint32_t hi = uint32_t(_val>>32);
+
+ return uint32_cntbits(lo)
+ + uint32_cntbits(hi)
+ ;
+#endif // BX_COMPILER_*
+ }
+
+ template<>
+ inline BX_CONSTEXPR_FUNC uint32_t uint32_cntbits(unsigned long _val)
+ {
+ return uint32_cntbits<unsigned long long>(_val);
+ }
+
+ template<> inline BX_CONSTEXPR_FUNC uint32_t uint32_cntbits(uint8_t _val) { return uint32_cntbits<uint32_t>(_val); }
+ template<> inline BX_CONSTEXPR_FUNC uint32_t uint32_cntbits(int8_t _val) { return uint32_cntbits<uint8_t >(_val); }
+ template<> inline BX_CONSTEXPR_FUNC uint32_t uint32_cntbits(uint16_t _val) { return uint32_cntbits<uint32_t>(_val); }
+ template<> inline BX_CONSTEXPR_FUNC uint32_t uint32_cntbits(int16_t _val) { return uint32_cntbits<uint16_t>(_val); }
+ template<> inline BX_CONSTEXPR_FUNC uint32_t uint32_cntbits(int32_t _val) { return uint32_cntbits<uint32_t>(_val); }
+ template<> inline BX_CONSTEXPR_FUNC uint32_t uint32_cntbits(int64_t _val) { return uint32_cntbits<uint64_t>(_val); }
+
+ template<>
inline BX_CONSTEXPR_FUNC uint32_t uint32_cntlz(uint32_t _val)
{
+#if BX_COMPILER_GCC || BX_COMPILER_CLANG
+ return 0 == _val ? 32 : __builtin_clz(_val);
+#else
const uint32_t tmp0 = uint32_srl(_val, 1);
const uint32_t tmp1 = uint32_or(tmp0, _val);
const uint32_t tmp2 = uint32_srl(tmp1, 2);
@@ -346,18 +383,76 @@ namespace bx
const uint32_t result = uint32_cntbits(tmpA);
return result;
+#endif // BX_COMPILER_*
+ }
+
+ template<>
+ inline BX_CONSTEXPR_FUNC uint32_t uint32_cntlz(unsigned long long _val)
+ {
+#if BX_COMPILER_GCC || BX_COMPILER_CLANG
+ return 0 == _val ? 64 : __builtin_clzll(_val);
+#else
+ return _val & UINT64_C(0xffffffff00000000)
+ ? uint32_cntlz(uint32_t(_val>>32) )
+ : uint32_cntlz(uint32_t(_val) ) + 32
+ ;
+#endif // BX_COMPILER_*
+ }
+
+ template<>
+ inline BX_CONSTEXPR_FUNC uint32_t uint32_cntlz(unsigned long _val)
+ {
+ return uint32_cntlz<unsigned long long>(_val);
}
+ template<> inline BX_CONSTEXPR_FUNC uint32_t uint32_cntlz(uint8_t _val) { return uint32_cntlz<uint32_t>(_val)-24; }
+ template<> inline BX_CONSTEXPR_FUNC uint32_t uint32_cntlz(int8_t _val) { return uint32_cntlz<uint8_t >(_val); }
+ template<> inline BX_CONSTEXPR_FUNC uint32_t uint32_cntlz(uint16_t _val) { return uint32_cntlz<uint32_t>(_val)-16; }
+ template<> inline BX_CONSTEXPR_FUNC uint32_t uint32_cntlz(int16_t _val) { return uint32_cntlz<uint16_t>(_val); }
+ template<> inline BX_CONSTEXPR_FUNC uint32_t uint32_cntlz(int32_t _val) { return uint32_cntlz<uint32_t>(_val); }
+ template<> inline BX_CONSTEXPR_FUNC uint32_t uint32_cntlz(int64_t _val) { return uint32_cntlz<uint64_t>(_val); }
+
+ template<>
inline BX_CONSTEXPR_FUNC uint32_t uint32_cnttz(uint32_t _val)
{
+#if BX_COMPILER_GCC || BX_COMPILER_CLANG
+ return 0 == _val ? 32 : __builtin_ctz(_val);
+#else
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;
+#endif // BX_COMPILER_*
+ }
+
+ template<>
+ inline BX_CONSTEXPR_FUNC uint32_t uint32_cnttz(unsigned long long _val)
+ {
+#if BX_COMPILER_GCC || BX_COMPILER_CLANG
+ return 0 == _val ? 64 : __builtin_ctzll(_val);
+#else
+ return _val & UINT64_C(0xffffffff)
+ ? uint32_cnttz(uint32_t(_val) )
+ : uint32_cnttz(uint32_t(_val>>32) ) + 32
+ ;
+#endif // BX_COMPILER_*
+ }
+
+ template<>
+ inline BX_CONSTEXPR_FUNC uint32_t uint32_cnttz(unsigned long _val)
+ {
+ return uint32_cnttz<unsigned long long>(_val);
}
+ template<> inline BX_CONSTEXPR_FUNC uint32_t uint32_cnttz(uint8_t _val) { return bx::min(8u, uint32_cnttz<uint32_t>(_val) ); }
+ template<> inline BX_CONSTEXPR_FUNC uint32_t uint32_cnttz(int8_t _val) { return uint32_cnttz<uint8_t >(_val); }
+ template<> inline BX_CONSTEXPR_FUNC uint32_t uint32_cnttz(uint16_t _val) { return bx::min(16u, uint32_cnttz<uint32_t>(_val) ); }
+ template<> inline BX_CONSTEXPR_FUNC uint32_t uint32_cnttz(int16_t _val) { return uint32_cnttz<uint16_t>(_val); }
+ template<> inline BX_CONSTEXPR_FUNC uint32_t uint32_cnttz(int32_t _val) { return uint32_cnttz<uint32_t>(_val); }
+ template<> inline BX_CONSTEXPR_FUNC uint32_t uint32_cnttz(int64_t _val) { return uint32_cnttz<uint64_t>(_val); }
+
inline BX_CONSTEXPR_FUNC uint32_t uint32_part1by1(uint32_t _a)
{
// shuffle:
@@ -468,6 +563,66 @@ namespace bx
;
}
+ inline BX_CONSTEXPR_FUNC uint64_t uint64_li(uint64_t _a)
+ {
+ return _a;
+ }
+
+ inline BX_CONSTEXPR_FUNC uint64_t uint64_dec(uint64_t _a)
+ {
+ return _a - 1;
+ }
+
+ inline BX_CONSTEXPR_FUNC uint64_t uint64_inc(uint64_t _a)
+ {
+ return _a + 1;
+ }
+
+ inline BX_CONSTEXPR_FUNC uint64_t uint64_not(uint64_t _a)
+ {
+ return ~_a;
+ }
+
+ inline BX_CONSTEXPR_FUNC uint64_t uint64_neg(uint64_t _a)
+ {
+ return -(int32_t)_a;
+ }
+
+ inline BX_CONSTEXPR_FUNC uint64_t uint64_ext(uint64_t _a)
+ {
+ return ( (int32_t)_a)>>31;
+ }
+
+ inline BX_CONSTEXPR_FUNC uint64_t uint64_and(uint64_t _a, uint64_t _b)
+ {
+ return _a & _b;
+ }
+
+ inline BX_CONSTEXPR_FUNC uint64_t uint64_andc(uint64_t _a, uint64_t _b)
+ {
+ return _a & ~_b;
+ }
+
+ inline BX_CONSTEXPR_FUNC uint64_t uint64_xor(uint64_t _a, uint64_t _b)
+ {
+ return _a ^ _b;
+ }
+
+ inline BX_CONSTEXPR_FUNC uint64_t uint64_xorl(uint64_t _a, uint64_t _b)
+ {
+ return !_a != !_b;
+ }
+
+ inline BX_CONSTEXPR_FUNC uint64_t uint64_or(uint64_t _a, uint64_t _b)
+ {
+ return _a | _b;
+ }
+
+ inline BX_CONSTEXPR_FUNC uint64_t uint64_orc(uint64_t _a, uint64_t _b)
+ {
+ return _a | ~_b;
+ }
+
inline BX_CONSTEXPR_FUNC uint64_t uint64_sll(uint64_t _a, int32_t _sa)
{
return _a << _sa;
@@ -537,9 +692,10 @@ namespace bx
return result;
}
- inline BX_CONSTEXPR_FUNC uint32_t strideAlign16(uint32_t _offset, uint32_t _stride)
+ template<uint32_t Min>
+ inline BX_CONSTEXPR_FUNC uint32_t strideAlign(uint32_t _offset, uint32_t _stride)
{
- const uint32_t align = uint32_lcm(16, _stride);
+ const uint32_t align = uint32_lcm(Min, _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);
@@ -549,16 +705,71 @@ namespace bx
return result;
}
- inline BX_CONSTEXPR_FUNC uint32_t strideAlign256(uint32_t _offset, uint32_t _stride)
+ template<typename Ty>
+ inline BX_CONSTEXPR_FUNC bool isAligned(Ty _a, int32_t _align)
{
- 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);
+ const Ty mask = Ty(_align - 1);
+ return 0 == (_a & mask);
+ }
- return result;
+ template<typename Ty>
+ inline BX_CONSTEXPR_FUNC bool isAligned(Ty* _ptr, int32_t _align)
+ {
+ union { const void* ptr; uintptr_t addr; } un = { _ptr };
+ return isAligned(un.addr, _align);
+ }
+
+ template<typename Ty>
+ inline BX_CONSTEXPR_FUNC bool isAligned(const Ty* _ptr, int32_t _align)
+ {
+ union { const void* ptr; uintptr_t addr; } un = { _ptr };
+ return isAligned(un.addr, _align);
+ }
+
+ template<typename Ty>
+ inline BX_CONSTEXPR_FUNC Ty alignDown(Ty _a, int32_t _align)
+ {
+ const Ty mask = Ty(_align - 1);
+ return Ty(_a & ~mask);
+ }
+
+ template<typename Ty>
+ inline BX_CONSTEXPR_FUNC Ty* alignDown(Ty* _ptr, int32_t _align)
+ {
+ union { Ty* ptr; uintptr_t addr; } un = { _ptr };
+ un.addr = alignDown(un.addr, _align);
+ return un.ptr;
+ }
+
+ template<typename Ty>
+ inline BX_CONSTEXPR_FUNC const Ty* alignDown(const Ty* _ptr, int32_t _align)
+ {
+ union { const Ty* ptr; uintptr_t addr; } un = { _ptr };
+ un.addr = alignDown(un.addr, _align);
+ return un.ptr;
+ }
+
+ template<typename Ty>
+ inline BX_CONSTEXPR_FUNC Ty alignUp(Ty _a, int32_t _align)
+ {
+ const Ty mask = Ty(_align - 1);
+ return Ty( (_a + mask) & ~mask);
+ }
+
+ template<typename Ty>
+ inline BX_CONSTEXPR_FUNC Ty* alignUp(Ty* _ptr, int32_t _align)
+ {
+ union { Ty* ptr; uintptr_t addr; } un = { _ptr };
+ un.addr = alignUp(un.addr, _align);
+ return un.ptr;
+ }
+
+ template<typename Ty>
+ inline BX_CONSTEXPR_FUNC const Ty* alignUp(const Ty* _ptr, int32_t _align)
+ {
+ union { const Ty* ptr; uintptr_t addr; } un = { _ptr };
+ un.addr = alignUp(un.addr, _align);
+ return un.ptr;
}
inline BX_CONST_FUNC uint16_t halfFromFloat(float _a)
diff --git a/3rdparty/bx/include/bx/macros.h b/3rdparty/bx/include/bx/macros.h
index 9c72182486b..61401af8650 100644
--- a/3rdparty/bx/include/bx/macros.h
+++ b/3rdparty/bx/include/bx/macros.h
@@ -1,15 +1,17 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
+#ifndef BX_H_HEADER_GUARD
+# error "Do not include macros.h directly #include <bx/bx.h> instead."
+#endif // BX_H_HEADER_GUARD
+
#ifndef BX_MACROS_H_HEADER_GUARD
#define BX_MACROS_H_HEADER_GUARD
-#include "bx.h"
-
///
-#if BX_COMPILER_MSVC
+#if BX_COMPILER_MSVC && (!defined(_MSVC_TRADITIONAL) || _MSVC_TRADITIONAL)
// Workaround MSVS bug...
# define BX_VA_ARGS_PASS(...) BX_VA_ARGS_PASS_1_ __VA_ARGS__ BX_VA_ARGS_PASS_2_
# define BX_VA_ARGS_PASS_1_ (
@@ -41,12 +43,6 @@
#define BX_FILE_LINE_LITERAL "" __FILE__ "(" BX_STRINGIZE(__LINE__) "): "
///
-#define BX_ALIGN_MASK(_value, _mask) ( ( (_value)+(_mask) ) & ( (~0)&(~(_mask) ) ) )
-#define BX_ALIGN_16(_value) BX_ALIGN_MASK(_value, 0xf)
-#define BX_ALIGN_256(_value) BX_ALIGN_MASK(_value, 0xff)
-#define BX_ALIGN_4096(_value) BX_ALIGN_MASK(_value, 0xfff)
-
-///
#define BX_ALIGNOF(_type) __alignof(_type)
#if defined(__has_feature)
@@ -70,7 +66,7 @@
# define BX_UNLIKELY(_x) __builtin_expect(!!(_x), 0)
# define BX_NO_INLINE __attribute__( (noinline) )
# define BX_NO_RETURN __attribute__( (noreturn) )
-# define BX_CONST_FUNC __attribute__( (const) )
+# define BX_CONST_FUNC __attribute__( (pure) )
# if BX_COMPILER_GCC >= 70000
# define BX_FALLTHROUGH __attribute__( (fallthrough) )
@@ -81,11 +77,9 @@
# define BX_NO_VTABLE
# define BX_PRINTF_ARGS(_format, _args) __attribute__( (format(__printf__, _format, _args) ) )
-# if BX_CLANG_HAS_FEATURE(cxx_thread_local)
-# define BX_THREAD_LOCAL __thread
-# endif // BX_COMPILER_CLANG
-
-# if (!BX_PLATFORM_OSX && (BX_COMPILER_GCC >= 40200)) || (BX_COMPILER_GCC >= 40500)
+# if BX_CLANG_HAS_FEATURE(cxx_thread_local) \
+ || (!BX_PLATFORM_OSX && (BX_COMPILER_GCC >= 40200) ) \
+ || (BX_COMPILER_GCC >= 40500)
# define BX_THREAD_LOCAL __thread
# endif // BX_COMPILER_GCC
@@ -151,7 +145,7 @@
#define BX_UNUSED_11(_a1, _a2, _a3, _a4, _a5, _a6, _a7, _a8, _a9, _a10, _a11) BX_UNUSED_10(_a1, _a2, _a3, _a4, _a5, _a6, _a7, _a8, _a9, _a10); BX_UNUSED_1(_a11)
#define BX_UNUSED_12(_a1, _a2, _a3, _a4, _a5, _a6, _a7, _a8, _a9, _a10, _a11, _a12) BX_UNUSED_11(_a1, _a2, _a3, _a4, _a5, _a6, _a7, _a8, _a9, _a10, _a11); BX_UNUSED_1(_a12)
-#if BX_COMPILER_MSVC
+#if BX_COMPILER_MSVC && (!defined(_MSVC_TRADITIONAL) || _MSVC_TRADITIONAL)
// Workaround MSVS bug...
# define BX_UNUSED(...) BX_MACRO_DISPATCHER(BX_UNUSED_, __VA_ARGS__) BX_VA_ARGS_PASS(__VA_ARGS__)
#else
@@ -203,16 +197,24 @@
# define BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG_GCC(_x)
#endif // BX_COMPILER_
-///
+/// No default constructor.
#define BX_CLASS_NO_DEFAULT_CTOR(_class) \
- private: _class()
+ _class() = delete
-#define BX_CLASS_NO_COPY(_class) \
- private: _class(const _class& _rhs)
+/// No copy constructor.
+#define BX_CLASS_NO_COPY_CTOR(_class) \
+ _class(const _class& _rhs) = delete
-#define BX_CLASS_NO_ASSIGNMENT(_class) \
- private: _class& operator=(const _class& _rhs)
+/// No copy assignment operator.
+#define BX_CLASS_NO_COPY_ASSIGNMENT(_class) \
+ _class& operator=(const _class& _rhs) = delete
+/// No copy construcor, and copy assignment operator.
+#define BX_CLASS_NO_COPY(_class) \
+ BX_CLASS_NO_COPY_CTOR(_class); \
+ BX_CLASS_NO_COPY_ASSIGNMENT(_class)
+
+///
#define BX_CLASS_ALLOCATOR(_class) \
public: void* operator new(size_t _size); \
public: void operator delete(void* _ptr); \
@@ -224,23 +226,57 @@
#define BX_CLASS_3(_class, _a1, _a2, _a3) BX_CLASS_2(_class, _a1, _a2); BX_CLASS_1(_class, _a3)
#define BX_CLASS_4(_class, _a1, _a2, _a3, _a4) BX_CLASS_3(_class, _a1, _a2, _a3); BX_CLASS_1(_class, _a4)
-#if BX_COMPILER_MSVC
+#if BX_COMPILER_MSVC && (!defined(_MSVC_TRADITIONAL) || _MSVC_TRADITIONAL)
# define BX_CLASS(_class, ...) BX_MACRO_DISPATCHER(BX_CLASS_, __VA_ARGS__) BX_VA_ARGS_PASS(_class, __VA_ARGS__)
#else
# define BX_CLASS(_class, ...) BX_MACRO_DISPATCHER(BX_CLASS_, __VA_ARGS__)(_class, __VA_ARGS__)
#endif // BX_COMPILER_MSVC
-#ifndef BX_CHECK
-# define BX_CHECK(_condition, ...) BX_NOOP()
-#endif // BX_CHECK
+#ifndef BX_ASSERT
+# if BX_CONFIG_DEBUG
+# define BX_ASSERT _BX_ASSERT
+# else
+# define BX_ASSERT(_condition, ...) BX_NOOP()
+# endif // BX_CONFIG_DEBUG
+#endif // BX_ASSERT
#ifndef BX_TRACE
-# define BX_TRACE(...) BX_NOOP()
+# if BX_CONFIG_DEBUG
+# define BX_TRACE _BX_TRACE
+# else
+# define BX_TRACE(...) BX_NOOP()
+# endif // BX_CONFIG_DEBUG
#endif // BX_TRACE
#ifndef BX_WARN
-# define BX_WARN(_condition, ...) BX_NOOP()
-#endif // BX_CHECK
+# if BX_CONFIG_DEBUG
+# define BX_WARN _BX_WARN
+# else
+# define BX_WARN(_condition, ...) BX_NOOP()
+# endif // BX_CONFIG_DEBUG
+#endif // BX_ASSERT
+
+#define _BX_TRACE(_format, ...) \
+ BX_MACRO_BLOCK_BEGIN \
+ bx::debugPrintf(__FILE__ "(" BX_STRINGIZE(__LINE__) "): BX " _format "\n", ##__VA_ARGS__); \
+ BX_MACRO_BLOCK_END
+
+#define _BX_WARN(_condition, _format, ...) \
+ BX_MACRO_BLOCK_BEGIN \
+ if (!BX_IGNORE_C4127(_condition) ) \
+ { \
+ BX_TRACE("WARN " _format, ##__VA_ARGS__); \
+ } \
+ BX_MACRO_BLOCK_END
+
+#define _BX_ASSERT(_condition, _format, ...) \
+ BX_MACRO_BLOCK_BEGIN \
+ if (!BX_IGNORE_C4127(_condition) ) \
+ { \
+ BX_TRACE("ASSERT " _format, ##__VA_ARGS__); \
+ bx::debugBreak(); \
+ } \
+ BX_MACRO_BLOCK_END
// static_assert sometimes causes unused-local-typedef...
BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG("-Wunused-local-typedef")
diff --git a/3rdparty/bx/include/bx/maputil.h b/3rdparty/bx/include/bx/maputil.h
index 78ce6b6f84c..712e2331e0a 100644
--- a/3rdparty/bx/include/bx/maputil.h
+++ b/3rdparty/bx/include/bx/maputil.h
@@ -1,6 +1,6 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_MAPUTIL_H_HEADER_GUARD
diff --git a/3rdparty/bx/include/bx/math.h b/3rdparty/bx/include/bx/math.h
index c751efad50b..a02549b5fe8 100644
--- a/3rdparty/bx/include/bx/math.h
+++ b/3rdparty/bx/include/bx/math.h
@@ -1,10 +1,8 @@
/*
- * Copyright 2011-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2011-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
-// FPU math lib
-
#ifndef BX_MATH_H_HEADER_GUARD
#define BX_MATH_H_HEADER_GUARD
@@ -13,27 +11,11 @@
namespace bx
{
- constexpr float kPi = 3.1415926535897932384626433832795f;
- constexpr float kPi2 = 6.2831853071795864769252867665590f;
- constexpr float kInvPi = 1.0f/kPi;
- constexpr float kPiHalf = 1.5707963267948966192313216916398f;
- constexpr float kPiQuarter = 0.7853981633974483096156608458199f;
- constexpr float kSqrt2 = 1.4142135623730950488016887242097f;
- constexpr float kLogNat10 = 2.3025850929940456840179914546844f;
- constexpr float kInvLogNat2 = 1.4426950408889634073599246810019f;
- constexpr float kLogNat2Hi = 0.6931471805599453094172321214582f;
- constexpr float kLogNat2Lo = 1.90821492927058770002e-10f;
- constexpr float kE = 2.7182818284590452353602874713527f;
- constexpr float kNearZero = 1.0f/float(1 << 28);
- constexpr float kFloatMin = 1.175494e-38f;
- constexpr float kFloatMax = 3.402823e+38f;
- extern const float kInfinity;
-
///
typedef float (*LerpFn)(float _a, float _b, float _t);
///
- struct Handness
+ struct Handedness
{
enum Enum
{
@@ -52,12 +34,89 @@ namespace bx
};
};
+ /// Structure initializer types.
+ namespace init
+ {
+ /// Fields are left uninitialized.
+ ///
+ struct NoneTag {};
+ constexpr NoneTag None;
+
+ /// Fields are initialized to zero.
+ ///
+ struct ZeroTag {};
+ constexpr ZeroTag Zero;
+
+ /// Fields are initialized to identity value.
+ ///
+ struct IdentityTag {};
+ constexpr IdentityTag Identity;
+ }
+
///
struct Vec3
{
+ Vec3() = delete;
+
+ ///
+ Vec3(init::NoneTag);
+
+ ///
+ constexpr Vec3(init::ZeroTag);
+
+ ///
+ constexpr Vec3(init::IdentityTag);
+
+ ///
+ explicit constexpr Vec3(float _v);
+
+ ///
+ constexpr Vec3(float _x, float _y, float _z);
+
float x, y, z;
};
+ ///
+ struct Plane
+ {
+ Plane() = delete;
+
+ ///
+ Plane(init::NoneTag);
+
+ ///
+ constexpr Plane(init::ZeroTag);
+
+ ///
+ constexpr Plane(init::IdentityTag);
+
+ ///
+ constexpr Plane(Vec3 _normal, float _dist);
+
+ Vec3 normal;
+ float dist;
+ };
+
+ ///
+ struct Quaternion
+ {
+ Quaternion() = delete;
+
+ ///
+ Quaternion(init::NoneTag);
+
+ ///
+ constexpr Quaternion(init::ZeroTag);
+
+ ///
+ constexpr Quaternion(init::IdentityTag);
+
+ ///
+ constexpr Quaternion(float _x, float _y, float _z, float _w);
+
+ float x, y, z, w;
+ };
+
/// Returns converted the argument _deg to radians.
///
BX_CONST_FUNC float toRad(float _deg);
@@ -112,21 +171,29 @@ namespace bx
/// Returns the largest integer value not greater than _f.
///
- BX_CONST_FUNC float floor(float _f);
+ BX_CONSTEXPR_FUNC float floor(float _f);
/// Returns the smallest integer value not less than _f.
///
- BX_CONST_FUNC float ceil(float _f);
+ BX_CONSTEXPR_FUNC float ceil(float _f);
/// Returns the nearest integer value to _f, rounding halfway cases away from zero,
///
- BX_CONST_FUNC float round(float _f);
+ BX_CONSTEXPR_FUNC float round(float _f);
/// Returns linear interpolation between two values _a and _b.
///
BX_CONSTEXPR_FUNC float lerp(float _a, float _b, float _t);
- /// Returns the sign of _a.
+ /// Returns inverse linear interpolation of _value between two values _a and _b.
+ ///
+ BX_CONSTEXPR_FUNC float invLerp(float _a, float _b, float _value);
+
+ /// Extracts the sign of value `_a`.
+ ///
+ /// @param[in] _a Value.
+ ///
+ /// @returns -1 if `_a` less than zero, 0 if `_a` is equal to 0, or +1 if `_a` is greater than zero.
///
BX_CONSTEXPR_FUNC float sign(float _a);
@@ -174,7 +241,7 @@ namespace bx
///
BX_CONST_FUNC float atan(float _a);
- /// Retruns the inverse tangent of _y/_x.
+ /// Returns the inverse tangent of _y/_x.
///
BX_CONST_FUNC float atan2(float _y, float _x);
@@ -205,7 +272,8 @@ namespace bx
/// Returns the base 2 logarithm of _a.
///
- BX_CONST_FUNC float log2(float _a);
+ template<typename Ty>
+ BX_CONST_FUNC Ty log2(Ty _a);
/// Returns the square root of _a.
///
@@ -224,315 +292,360 @@ namespace bx
///
BX_CONSTEXPR_FUNC float fract(float _a);
- /// Returns result of multipla and add (_a * _b + _c).
- ///
- BX_CONSTEXPR_FUNC float mad(float _a, float _b, float _c);
-
- /// Returns the floating-point remainder of the division operation _a/_b.
- ///
- BX_CONST_FUNC float mod(float _a, float _b);
-
- ///
- BX_CONSTEXPR_FUNC bool equal(float _a, float _b, float _epsilon);
-
+ /// Returns result of negated multiply-sub operation -(_a * _b - _c) -> _c - _a * _b.
///
- BX_CONST_FUNC bool equal(const float* _a, const float* _b, uint32_t _num, float _epsilon);
+ BX_CONSTEXPR_FUNC float nms(float _a, float _b, float _c);
+ /// Returns result of addition (_a + _b).
///
- BX_CONST_FUNC float wrap(float _a, float _wrap);
+ BX_CONSTEXPR_FUNC float add(float _a, float _b);
+ /// Returns result of subtracion (_a - _b).
///
- BX_CONSTEXPR_FUNC float step(float _edge, float _a);
+ BX_CONSTEXPR_FUNC float sub(float _a, float _b);
+ /// Returns result of multiply (_a * _b).
///
- BX_CONSTEXPR_FUNC float pulse(float _a, float _start, float _end);
-
- ///
- BX_CONSTEXPR_FUNC float smoothStep(float _a);
-
- ///
- BX_CONSTEXPR_FUNC float bias(float _time, float _bias);
-
- ///
- BX_CONSTEXPR_FUNC float gain(float _time, float _gain);
-
- ///
- BX_CONST_FUNC float angleDiff(float _a, float _b);
-
- /// Returns shortest distance linear interpolation between two angles.
- ///
- BX_CONST_FUNC float angleLerp(float _a, float _b, float _t);
+ BX_CONSTEXPR_FUNC float mul(float _a, float _b);
+ /// Returns result of multiply and add (_a * _b + _c).
///
- Vec3 load(const void* _ptr);
-
- ///
- void store(void* _ptr, const Vec3& _a);
-
- ///
- BX_CONSTEXPR_FUNC Vec3 abs(const Vec3& _a);
-
- ///
- BX_CONSTEXPR_FUNC Vec3 neg(const Vec3& _a);
-
- ///
- BX_CONSTEXPR_FUNC Vec3 add(const Vec3& _a, const Vec3& _b);
-
- ///
- BX_CONSTEXPR_FUNC Vec3 add(const Vec3& _a, float _b);
-
- ///
- BX_CONSTEXPR_FUNC Vec3 sub(const Vec3& _a, const Vec3& _b);
-
- ///
- BX_CONSTEXPR_FUNC Vec3 sub(const Vec3& _a, float _b);
-
- ///
- BX_CONSTEXPR_FUNC Vec3 mul(const Vec3& _a, const Vec3& _b);
-
- ///
- BX_CONSTEXPR_FUNC Vec3 mul(const Vec3& _a, float _b);
-
- ///
- BX_CONSTEXPR_FUNC Vec3 mad(const Vec3& _a, const Vec3& _b, const Vec3& _c);
-
- ///
- BX_CONSTEXPR_FUNC float dot(const Vec3& _a, const Vec3& _b);
-
- ///
- BX_CONSTEXPR_FUNC Vec3 cross(const Vec3& _a, const Vec3& _b);
-
- ///
- BX_CONST_FUNC float length(const Vec3& _a);
-
- ///
- BX_CONSTEXPR_FUNC Vec3 lerp(const Vec3& _a, const Vec3& _b, float _t);
-
- ///
- BX_CONSTEXPR_FUNC Vec3 lerp(const Vec3& _a, const Vec3& _b, const Vec3& _t);
+ BX_CONSTEXPR_FUNC float mad(float _a, float _b, float _c);
+ /// Returns reciprocal of _a.
///
- BX_CONST_FUNC Vec3 normalize(const Vec3& _a);
+ BX_CONSTEXPR_FUNC float rcp(float _a);
+ /// Returns the floating-point remainder of the division operation _a/_b.
///
- BX_CONSTEXPR_FUNC Vec3 min(const Vec3& _a, const Vec3& _b);
+ BX_CONST_FUNC float mod(float _a, float _b);
///
- BX_CONSTEXPR_FUNC Vec3 max(const Vec3& _a, const Vec3& _b);
+ BX_CONSTEXPR_FUNC bool isEqual(float _a, float _b, float _epsilon);
///
- BX_CONSTEXPR_FUNC Vec3 rcp(const Vec3& _a);
+ BX_CONST_FUNC bool isEqual(const float* _a, const float* _b, uint32_t _num, float _epsilon);
///
- void calcTangentFrame(Vec3& _outT, Vec3& _outB, const Vec3& _n);
+ BX_CONST_FUNC float wrap(float _a, float _wrap);
///
- void calcTangentFrame(Vec3& _outT, Vec3& _outB, const Vec3& _n, float _angle);
+ BX_CONSTEXPR_FUNC float step(float _edge, float _a);
///
- BX_CONST_FUNC Vec3 fromLatLong(float _u, float _v);
+ BX_CONSTEXPR_FUNC float pulse(float _a, float _start, float _end);
///
- void toLatLong(float* _outU, float* _outV, const Vec3& _dir);
+ BX_CONSTEXPR_FUNC float smoothStep(float _a);
///
- void vec3Add(float* _result, const float* _a, const float* _b);
+ BX_CONST_FUNC float invSmoothStep(float _a);
///
- void vec3Sub(float* _result, const float* _a, const float* _b);
+ BX_CONSTEXPR_FUNC float bias(float _time, float _bias);
///
- void vec3Mul(float* _result, const float* _a, const float* _b);
+ BX_CONSTEXPR_FUNC float gain(float _time, float _gain);
///
- void vec3Mul(float* _result, const float* _a, float _b);
+ BX_CONST_FUNC float angleDiff(float _a, float _b);
+ /// Returns shortest distance linear interpolation between two angles.
///
- float vec3Dot(const float* _a, const float* _b);
+ BX_CONST_FUNC float angleLerp(float _a, float _b, float _t);
///
- void vec3Cross(float* _result, const float* _a, const float* _b);
+ template<typename Ty>
+ Ty load(const void* _ptr);
///
- float vec3Length(const float* _a);
+ template<typename Ty>
+ void store(void* _ptr, const Ty& _a);
///
- float vec3Norm(float* _result, const float* _a);
+ BX_CONSTEXPR_FUNC Vec3 round(const Vec3 _a);
- /// Calculate tangent frame from normal.
///
- void vec3TangentFrame(const float* _n, float* _t, float* _b);
+ BX_CONSTEXPR_FUNC Vec3 abs(const Vec3 _a);
- /// Calculate tangent frame from normal and angle.
///
- void vec3TangentFrame(const float* _n, float* _t, float* _b, float _angle);
+ BX_CONSTEXPR_FUNC Vec3 neg(const Vec3 _a);
///
- void vec3FromLatLong(float* _vec, float _u, float _v);
+ BX_CONSTEXPR_FUNC Vec3 add(const Vec3 _a, const Vec3 _b);
- /// Convert direction to 2D latitude and longitude.
///
- /// @param[out] _outU U-coordinate.
- /// @param[out] _outV V-coordinate.
- /// @param[in] _dir Normalized direction vector.
- ///
- void vec3ToLatLong(float* _outU, float* _outV, const float* _dir);
+ BX_CONSTEXPR_FUNC Vec3 add(const Vec3 _a, float _b);
///
- void quatIdentity(float* _result);
+ BX_CONSTEXPR_FUNC Vec3 sub(const Vec3 _a, const Vec3 _b);
///
- void quatMove(float* _result, const float* _a);
+ BX_CONSTEXPR_FUNC Vec3 sub(const Vec3 _a, float _b);
///
- void quatMulXYZ(float* _result, const float* _qa, const float* _qb);
+ BX_CONSTEXPR_FUNC Vec3 mul(const Vec3 _a, const Vec3 _b);
///
- void quatMul(float* _result, const float* _qa, const float* _qb);
+ BX_CONSTEXPR_FUNC Vec3 mul(const Vec3 _a, float _b);
///
- void quatInvert(float* _result, const float* _quat);
+ BX_CONSTEXPR_FUNC Vec3 div(const Vec3 _a, const Vec3 _b);
///
- float quatDot(const float* _a, const float* _b);
+ BX_CONSTEXPR_FUNC Vec3 div(const Vec3 _a, float _b);
+ /// Returns result of negated multiply-sub operation -(_a * _b - _c) -> _c - _a * _b.
///
- void quatNorm(float* _result, const float* _quat);
+ BX_CONSTEXPR_FUNC Vec3 nms(const Vec3 _a, const float _b, const Vec3 _c);
+ /// Returns result of negated multiply-sub operation -(_a * _b - _c) -> _c - _a * _b.
///
- void quatToEuler(float* _result, const float* _quat);
+ BX_CONSTEXPR_FUNC Vec3 nms(const Vec3 _a, const Vec3 _b, const Vec3 _c);
///
- void quatRotateAxis(float* _result, const float* _axis, float _angle);
+ BX_CONSTEXPR_FUNC Vec3 mad(const Vec3 _a, const float _b, const Vec3 _c);
///
- void quatRotateX(float* _result, float _ax);
+ BX_CONSTEXPR_FUNC Vec3 mad(const Vec3 _a, const Vec3 _b, const Vec3 _c);
///
- void quatRotateY(float* _result, float _ay);
+ BX_CONSTEXPR_FUNC float dot(const Vec3 _a, const Vec3 _b);
///
- void quatRotateZ(float* _result, float _az);
+ BX_CONSTEXPR_FUNC Vec3 cross(const Vec3 _a, const Vec3 _b);
///
- void vec3MulQuat(float* _result, const float* _vec, const float* _quat);
+ BX_CONST_FUNC float length(const Vec3 _a);
///
- void mtxIdentity(float* _result);
+ BX_CONST_FUNC float distanceSq(const Vec3 _a, const Vec3 _b);
///
- void mtxTranslate(float* _result, float _tx, float _ty, float _tz);
+ BX_CONST_FUNC float distance(const Vec3 _a, const Vec3 _b);
///
- void mtxScale(float* _result, float _sx, float _sy, float _sz);
+ BX_CONSTEXPR_FUNC Vec3 lerp(const Vec3 _a, const Vec3 _b, float _t);
///
- void mtxScale(float* _result, float _scale);
+ BX_CONSTEXPR_FUNC Vec3 lerp(const Vec3 _a, const Vec3 _b, const Vec3 _t);
///
- void mtxFromNormal(float* _result, const float* _normal, float _scale, const float* _pos);
+ BX_CONST_FUNC Vec3 normalize(const Vec3 _a);
///
- void mtxFromNormal(float* _result, const float* _normal, float _scale, const float* _pos, float _angle);
+ BX_CONSTEXPR_FUNC Vec3 min(const Vec3 _a, const Vec3 _b);
///
- void mtxQuat(float* _result, const float* _quat);
+ BX_CONSTEXPR_FUNC Vec3 max(const Vec3 _a, const Vec3 _b);
+ /// Returns component wise reciprocal of _a.
///
- void mtxQuatTranslation(float* _result, const float* _quat, const float* _translation);
+ BX_CONSTEXPR_FUNC Vec3 rcp(const Vec3 _a);
///
- void mtxQuatTranslationHMD(float* _result, const float* _quat, const float* _translation);
+ BX_CONSTEXPR_FUNC bool isEqual(const Vec3 _a, const Vec3 _b, float _epsilon);
///
- void mtxLookAtLh(float* _result, const Vec3& _eye, const Vec3& _at, const Vec3& _up = { 0.0f, 1.0f, 0.0f });
+ void calcTangentFrame(Vec3& _outT, Vec3& _outB, const Vec3 _n);
///
- void mtxLookAtRh(float* _result, const Vec3& _eye, const Vec3& _at, const Vec3& _up = { 0.0f, 1.0f, 0.0f });
+ void calcTangentFrame(Vec3& _outT, Vec3& _outB, const Vec3 _n, float _angle);
///
- void mtxLookAt(float* _result, const Vec3& _eye, const Vec3& _at, const Vec3& _up = { 0.0f, 1.0f, 0.0f });
+ BX_CONST_FUNC Vec3 fromLatLong(float _u, float _v);
///
- void mtxProj(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, float _far, bool _oglNdc);
+ void toLatLong(float* _outU, float* _outV, const Vec3 _dir);
///
- void mtxProj(float* _result, const float _fov[4], float _near, float _far, bool _oglNdc);
+ BX_CONSTEXPR_FUNC Quaternion invert(const Quaternion _a);
///
- void mtxProj(float* _result, float _fovy, float _aspect, float _near, float _far, bool _oglNdc);
+ BX_CONSTEXPR_FUNC Vec3 mulXyz(const Quaternion _a, const Quaternion _b);
///
- void mtxProjLh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, float _far, bool _oglNdc);
+ BX_CONSTEXPR_FUNC Quaternion add(const Quaternion _a, const Quaternion _b);
///
- void mtxProjLh(float* _result, const float _fov[4], float _near, float _far, bool _oglNdc);
+ BX_CONSTEXPR_FUNC Quaternion sub(const Quaternion _a, const Quaternion _b);
///
- void mtxProjLh(float* _result, float _fovy, float _aspect, float _near, float _far, bool _oglNdc);
+ BX_CONSTEXPR_FUNC Quaternion mul(const Quaternion _a, float _b);
///
- void mtxProjRh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, float _far, bool _oglNdc);
+ BX_CONSTEXPR_FUNC Quaternion mul(const Quaternion _a, const Quaternion _b);
///
- void mtxProjRh(float* _result, const float _fov[4], float _near, float _far, bool _oglNdc);
+ BX_CONSTEXPR_FUNC Vec3 mul(const Vec3 _v, const Quaternion _q);
///
- void mtxProjRh(float* _result, float _fovy, float _aspect, float _near, float _far, bool _oglNdc);
+ BX_CONSTEXPR_FUNC float dot(const Quaternion _a, const Quaternion _b);
///
- void mtxProjInf(float* _result, const float _fov[4], float _near, bool _oglNdc);
+ BX_CONSTEXPR_FUNC Quaternion normalize(const Quaternion _a);
///
- void mtxProjInf(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc);
+ BX_CONSTEXPR_FUNC Quaternion lerp(const Quaternion _a, const Quaternion _b, float _t);
///
- void mtxProjInf(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc);
+ BX_CONST_FUNC Quaternion fromEuler(const Vec3 _euler);
///
- void mtxProjInfLh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc);
+ BX_CONST_FUNC Vec3 toEuler(const Quaternion _a);
///
- void mtxProjInfLh(float* _result, const float _fov[4], float _near, bool _oglNdc);
+ BX_CONST_FUNC Vec3 toXAxis(const Quaternion _a);
///
- void mtxProjInfLh(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc);
+ BX_CONST_FUNC Vec3 toYAxis(const Quaternion _a);
///
- void mtxProjInfRh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc);
+ BX_CONST_FUNC Vec3 toZAxis(const Quaternion _a);
///
- void mtxProjInfRh(float* _result, const float _fov[4], float _near, bool _oglNdc);
+ BX_CONST_FUNC Quaternion fromAxisAngle(const Vec3 _axis, float _angle);
///
- void mtxProjInfRh(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc);
+ void toAxisAngle(Vec3& _outAxis, float& _outAngle, const Quaternion _a);
///
- void mtxProjRevInfLh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc);
+ BX_CONST_FUNC Quaternion rotateX(float _ax);
///
- void mtxProjRevInfLh(float* _result, const float _fov[4], float _near, bool _oglNdc);
+ BX_CONST_FUNC Quaternion rotateY(float _ay);
///
- void mtxProjRevInfLh(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc);
+ BX_CONST_FUNC Quaternion rotateZ(float _az);
///
- void mtxProjRevInfRh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc);
+ BX_CONSTEXPR_FUNC bool isEqual(const Quaternion _a, const Quaternion _b, float _epsilon);
///
- void mtxProjRevInfRh(float* _result, const float _fov[4], float _near, bool _oglNdc);
+ void mtxIdentity(float* _result);
///
- void mtxProjRevInfRh(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc);
+ void mtxTranslate(float* _result, float _tx, float _ty, float _tz);
///
- void mtxOrtho(float* _result, float _left, float _right, float _bottom, float _top, float _near, float _far, float _offset, bool _oglNdc);
+ void mtxScale(float* _result, float _sx, float _sy, float _sz);
///
- void mtxOrthoLh(float* _result, float _left, float _right, float _bottom, float _top, float _near, float _far, float _offset, bool _oglNdc);
+ void mtxScale(float* _result, float _scale);
///
- void mtxOrthoRh(float* _result, float _left, float _right, float _bottom, float _top, float _near, float _far, float _offset, bool _oglNdc);
+ void mtxFromNormal(
+ float* _result
+ , const Vec3& _normal
+ , float _scale
+ , const Vec3& _pos
+ );
+
+ ///
+ void mtxFromNormal(
+ float* _result
+ , const Vec3& _normal
+ , float _scale
+ , const Vec3& _pos
+ , float _angle
+ );
+
+ ///
+ void mtxFromQuaternion(float* _result, const Quaternion& _rotation);
+
+ ///
+ void mtxFromQuaternion(float* _result, const Quaternion& _rotation, const Vec3& _translation);
+
+ ///
+ void mtxLookAt(
+ float* _result
+ , const Vec3& _eye
+ , const Vec3& _at
+ , const Vec3& _up = { 0.0f, 1.0f, 0.0f }
+ , Handedness::Enum _handedness = Handedness::Left
+ );
+
+ ///
+ void mtxProj(
+ float* _result
+ , float _ut
+ , float _dt
+ , float _lt
+ , float _rt
+ , float _near
+ , float _far
+ , bool _homogeneousNdc
+ , Handedness::Enum _handedness = Handedness::Left
+ );
+
+ ///
+ void mtxProj(
+ float* _result
+ , const float _fov[4]
+ , float _near
+ , float _far
+ , bool _homogeneousNdc
+ , Handedness::Enum _handedness = Handedness::Left
+ );
+
+ ///
+ void mtxProj(
+ float* _result
+ , float _fovy
+ , float _aspect
+ , float _near
+ , float _far
+ , bool _homogeneousNdc
+ , Handedness::Enum _handedness = Handedness::Left
+ );
+
+ ///
+ void mtxProjInf(
+ float* _result
+ , const float _fov[4]
+ , float _near
+ , bool _homogeneousNdc
+ , Handedness::Enum _handedness = Handedness::Left
+ , NearFar::Enum _nearFar = NearFar::Default
+ );
+
+ ///
+ void mtxProjInf(
+ float* _result
+ , float _ut
+ , float _dt
+ , float _lt
+ , float _rt
+ , float _near
+ , bool _homogeneousNdc
+ , Handedness::Enum _handedness = Handedness::Left
+ , NearFar::Enum _nearFar = NearFar::Default
+ );
+
+ ///
+ void mtxProjInf(
+ float* _result
+ , float _fovy
+ , float _aspect
+ , float _near
+ , bool _homogeneousNdc
+ , Handedness::Enum _handedness = Handedness::Left
+ , NearFar::Enum _nearFar = NearFar::Default
+ );
+
+ ///
+ void mtxOrtho(
+ float* _result
+ , float _left
+ , float _right
+ , float _bottom
+ , float _top
+ , float _near
+ , float _far
+ , float _offset
+ , bool _homogeneousNdc
+ , Handedness::Enum _handedness = Handedness::Left
+ );
///
void mtxRotateX(float* _result, float _ax);
@@ -553,22 +666,27 @@ namespace bx
void mtxRotateZYX(float* _result, float _ax, float _ay, float _az);
///
- void mtxSRT(float* _result, float _sx, float _sy, float _sz, float _ax, float _ay, float _az, float _tx, float _ty, float _tz);
+ void mtxSRT(
+ float* _result
+ , float _sx
+ , float _sy
+ , float _sz
+ , float _ax
+ , float _ay
+ , float _az
+ , float _tx
+ , float _ty
+ , float _tz
+ );
///
- void vec3MulMtx(float* _result, const float* _vec, const float* _mat);
+ Vec3 mul(const Vec3& _vec, const float* _mat);
///
- void vec3MulMtxXyz0(float* _result, const float* _vec, const float* _mat);
+ Vec3 mulXyz0(const Vec3& _vec, const float* _mat);
///
- void vec3MulMtxH(float* _result, const float* _vec, const float* _mat);
-
- ///
- void vec4Mul(float* _result, const float* _a, const float* _b);
-
- ///
- void vec4Mul(float* _result, const float* _a, float _b);
+ Vec3 mulH(const Vec3& _vec, const float* _mat);
///
void vec4MulMtx(float* _result, const float* _vec, const float* _mat);
@@ -585,22 +703,26 @@ namespace bx
///
void mtxInverse(float* _result, const float* _a);
- /// Convert LH to RH projection matrix and vice versa.
///
- void mtxProjFlipHandedness(float* _dst, const float* _src);
+ void mtx3Cofactor(float* _result, const float* _a);
+
+ ///
+ void mtxCofactor(float* _result, const float* _a);
+
+ ///
+ Vec3 calcNormal(const Vec3& _va, const Vec3& _vb, const Vec3& _vc);
- /// Convert LH to RH view matrix and vice versa.
///
- void mtxViewFlipHandedness(float* _dst, const float* _src);
+ void calcPlane(Plane& _outPlane, const Vec3& _va, const Vec3& _vb, const Vec3& _vc);
///
- void calcNormal(float _result[3], const float _va[3], const float _vb[3], const float _vc[3]);
+ void calcPlane(Plane& _outPlane, const Vec3& _normal, const Vec3& _pos);
///
- void calcPlane(float _result[4], const float _va[3], const float _vb[3], const float _vc[3]);
+ BX_CONSTEXPR_FUNC float distance(const Plane& _plane, const Vec3& _pos);
///
- void calcPlane(float _result[4], const float _normal[3], const float _pos[3]);
+ BX_CONSTEXPR_FUNC bool isEqual(const Plane& _a, const Plane& _b, float _epsilon);
///
void calcLinearFit2D(float _result[2], const void* _points, uint32_t _stride, uint32_t _numPoints);
diff --git a/3rdparty/bx/include/bx/mpscqueue.h b/3rdparty/bx/include/bx/mpscqueue.h
index 003dfe8f4f8..7bb083b173e 100644
--- a/3rdparty/bx/include/bx/mpscqueue.h
+++ b/3rdparty/bx/include/bx/mpscqueue.h
@@ -1,6 +1,6 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_MPSCQUEUE_H_HEADER_GUARD
@@ -17,8 +17,8 @@ namespace bx
class MpScUnboundedQueueT
{
BX_CLASS(MpScUnboundedQueueT
+ , NO_DEFAULT_CTOR
, NO_COPY
- , NO_ASSIGNMENT
);
public:
@@ -47,8 +47,8 @@ namespace bx
class MpScUnboundedBlockingQueue
{
BX_CLASS(MpScUnboundedBlockingQueue
+ , NO_DEFAULT_CTOR
, NO_COPY
- , NO_ASSIGNMENT
);
public:
diff --git a/3rdparty/bx/include/bx/mutex.h b/3rdparty/bx/include/bx/mutex.h
index 213fc68c70e..4713b5da500 100644
--- a/3rdparty/bx/include/bx/mutex.h
+++ b/3rdparty/bx/include/bx/mutex.h
@@ -1,6 +1,6 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_MUTEX_H_HEADER_GUARD
@@ -15,7 +15,6 @@ namespace bx
{
BX_CLASS(Mutex
, NO_COPY
- , NO_ASSIGNMENT
);
public:
@@ -41,7 +40,6 @@ namespace bx
BX_CLASS(MutexScope
, NO_DEFAULT_CTOR
, NO_COPY
- , NO_ASSIGNMENT
);
public:
diff --git a/3rdparty/bx/include/bx/os.h b/3rdparty/bx/include/bx/os.h
index 92edacd21d1..4de2f6d8b8d 100644
--- a/3rdparty/bx/include/bx/os.h
+++ b/3rdparty/bx/include/bx/os.h
@@ -1,12 +1,11 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_OS_H_HEADER_GUARD
#define BX_OS_H_HEADER_GUARD
-#include "debug.h"
#include "filepath.h"
#if BX_PLATFORM_OSX
@@ -41,6 +40,10 @@ namespace bx
void* dlsym(void* _handle, const StringView& _symbol);
///
+ template<typename ProtoT>
+ ProtoT dlsym(void* _handle, const StringView& _symbol);
+
+ ///
bool getEnv(char* _out, uint32_t* _inOutSize, const StringView& _name);
///
@@ -52,6 +55,11 @@ namespace bx
///
void* exec(const char* const* _argv);
+ ///
+ BX_NO_RETURN void exit(int32_t _exitCode);
+
} // namespace bx
+#include "inline/os.inl"
+
#endif // BX_OS_H_HEADER_GUARD
diff --git a/3rdparty/bx/include/bx/pixelformat.h b/3rdparty/bx/include/bx/pixelformat.h
index c75b39836d5..c556b014e56 100644
--- a/3rdparty/bx/include/bx/pixelformat.h
+++ b/3rdparty/bx/include/bx/pixelformat.h
@@ -1,6 +1,6 @@
/*
- * Copyright 2011-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2011-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_PIXEL_FORMAT_H_HEADER_GUARD
@@ -41,6 +41,10 @@ namespace bx
///
float fromSnorm(int32_t _value, float _scale);
+ // A8
+ void packA8(void* _dst, const float* _src);
+ void unpackA8(float* _dst, const void* _src);
+
// R8
void packR8(void* _dst, const float* _src);
void unpackR8(float* _dst, const void* _src);
@@ -205,6 +209,10 @@ namespace bx
void packRgba32F(void* _dst, const float* _src);
void unpackRgba32F(float* _dst, const void* _src);
+ // B5G6R5
+ void packB5G6R5(void* _dst, const float* _src);
+ void unpackB5G6R5(float* _dst, const void* _src);
+
// R5G6B5
void packR5G6B5(void* _dst, const float* _src);
void unpackR5G6B5(float* _dst, const void* _src);
@@ -213,7 +221,7 @@ namespace bx
void packRgba4(void* _dst, const float* _src);
void unpackRgba4(float* _dst, const void* _src);
- // RGBA4
+ // BGRA4
void packBgra4(void* _dst, const float* _src);
void unpackBgra4(float* _dst, const void* _src);
diff --git a/3rdparty/bx/include/bx/platform.h b/3rdparty/bx/include/bx/platform.h
index e0031ec2c38..f14f9b680bf 100644
--- a/3rdparty/bx/include/bx/platform.h
+++ b/3rdparty/bx/include/bx/platform.h
@@ -1,6 +1,6 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_PLATFORM_H_HEADER_GUARD
@@ -16,7 +16,7 @@
#define BX_COMPILER_GCC 0
#define BX_COMPILER_MSVC 0
-// Endianess
+// Endianness
#define BX_CPU_ENDIAN_BIG 0
#define BX_CPU_ENDIAN_LITTLE 0
@@ -30,32 +30,36 @@
// C Runtime
#define BX_CRT_BIONIC 0
+#define BX_CRT_BSD 0
#define BX_CRT_GLIBC 0
#define BX_CRT_LIBCXX 0
#define BX_CRT_MINGW 0
#define BX_CRT_MSVC 0
#define BX_CRT_NEWLIB 0
-#ifndef BX_CRT_MUSL
-# define BX_CRT_MUSL 0
-#endif // BX_CRT_MUSL
-
#ifndef BX_CRT_NONE
# define BX_CRT_NONE 0
#endif // BX_CRT_NONE
+// Language standard version
+#define BX_LANGUAGE_CPP14 201402L
+#define BX_LANGUAGE_CPP17 201703L
+#define BX_LANGUAGE_CPP20 202002L
+#define BX_LANGUAGE_CPP23 202207L
+
// Platform
#define BX_PLATFORM_ANDROID 0
#define BX_PLATFORM_BSD 0
#define BX_PLATFORM_EMSCRIPTEN 0
+#define BX_PLATFORM_HAIKU 0
#define BX_PLATFORM_HURD 0
#define BX_PLATFORM_IOS 0
#define BX_PLATFORM_LINUX 0
#define BX_PLATFORM_NX 0
#define BX_PLATFORM_OSX 0
#define BX_PLATFORM_PS4 0
+#define BX_PLATFORM_PS5 0
#define BX_PLATFORM_RPI 0
-#define BX_PLATFORM_STEAMLINK 0
#define BX_PLATFORM_WINDOWS 0
#define BX_PLATFORM_WINRT 0
#define BX_PLATFORM_XBOXONE 0
@@ -133,12 +137,18 @@
#endif //
#if BX_CPU_PPC
-# undef BX_CPU_ENDIAN_BIG
-# define BX_CPU_ENDIAN_BIG 1
+// __BIG_ENDIAN__ is gcc predefined macro
+# if defined(__BIG_ENDIAN__)
+# undef BX_CPU_ENDIAN_BIG
+# define BX_CPU_ENDIAN_BIG 1
+# else
+# undef BX_CPU_ENDIAN_LITTLE
+# define BX_CPU_ENDIAN_LITTLE 1
+# endif
#else
# undef BX_CPU_ENDIAN_LITTLE
# define BX_CPU_ENDIAN_LITTLE 1
-#endif // BX_PLATFORM_
+#endif // BX_CPU_PPC
// http://sourceforge.net/apps/mediawiki/predef/index.php?title=Operating_Systems
#if defined(_DURANGO) || defined(_XBOX_ONE)
@@ -176,10 +186,6 @@
# include <sys/cdefs.h> // Defines __BIONIC__ and includes android/api-level.h
# undef BX_PLATFORM_ANDROID
# define BX_PLATFORM_ANDROID __ANDROID_API__
-#elif defined(__STEAMLINK__)
-// SteamLink compiler defines __linux__
-# undef BX_PLATFORM_STEAMLINK
-# define BX_PLATFORM_STEAMLINK 1
#elif defined(__VCCOREVER__)
// RaspberryPi compiler defines __linux__
# undef BX_PLATFORM_RPI
@@ -200,6 +206,9 @@
#elif defined(__ORBIS__)
# undef BX_PLATFORM_PS4
# define BX_PLATFORM_PS4 1
+#elif defined(__PROSPERO__)
+# undef BX_PLATFORM_PS5
+# define BX_PLATFORM_PS5 1
#elif defined(__FreeBSD__) \
|| defined(__FreeBSD_kernel__) \
|| defined(__NetBSD__) \
@@ -213,6 +222,9 @@
#elif defined(__NX__)
# undef BX_PLATFORM_NX
# define BX_PLATFORM_NX 1
+#elif defined(__HAIKU__)
+# undef BX_PLATFORM_HAIKU
+# define BX_PLATFORM_HAIKU 1
#endif //
#if !BX_CRT_NONE
@@ -229,54 +241,97 @@
# elif defined(__MINGW32__) || defined(__MINGW64__)
# undef BX_CRT_MINGW
# define BX_CRT_MINGW 1
-# elif defined(__apple_build_version__) || defined(__ORBIS__) || defined(__EMSCRIPTEN__) || defined(__llvm__)
+# elif defined(__apple_build_version__) || defined(__ORBIS__) || defined(__EMSCRIPTEN__) || defined(__llvm__) || defined(__HAIKU__)
# undef BX_CRT_LIBCXX
# define BX_CRT_LIBCXX 1
+# elif BX_PLATFORM_BSD
+# undef BX_CRT_BSD
+# define BX_CRT_BSD 1
# endif //
# if !BX_CRT_BIONIC \
+ && !BX_CRT_BSD \
&& !BX_CRT_GLIBC \
&& !BX_CRT_LIBCXX \
&& !BX_CRT_MINGW \
&& !BX_CRT_MSVC \
- && !BX_CRT_MUSL \
&& !BX_CRT_NEWLIB
# undef BX_CRT_NONE
# define BX_CRT_NONE 1
# endif // BX_CRT_*
#endif // !BX_CRT_NONE
+///
#define BX_PLATFORM_POSIX (0 \
|| BX_PLATFORM_ANDROID \
|| BX_PLATFORM_BSD \
|| BX_PLATFORM_EMSCRIPTEN \
+ || BX_PLATFORM_HAIKU \
|| BX_PLATFORM_HURD \
|| BX_PLATFORM_IOS \
|| BX_PLATFORM_LINUX \
|| BX_PLATFORM_NX \
|| BX_PLATFORM_OSX \
|| BX_PLATFORM_PS4 \
+ || BX_PLATFORM_PS5 \
|| BX_PLATFORM_RPI \
- || BX_PLATFORM_STEAMLINK \
)
+///
#define BX_PLATFORM_NONE !(0 \
|| BX_PLATFORM_ANDROID \
|| BX_PLATFORM_BSD \
|| BX_PLATFORM_EMSCRIPTEN \
+ || BX_PLATFORM_HAIKU \
|| BX_PLATFORM_HURD \
|| BX_PLATFORM_IOS \
|| BX_PLATFORM_LINUX \
|| BX_PLATFORM_NX \
|| BX_PLATFORM_OSX \
|| BX_PLATFORM_PS4 \
+ || BX_PLATFORM_PS5 \
|| BX_PLATFORM_RPI \
- || BX_PLATFORM_STEAMLINK \
|| BX_PLATFORM_WINDOWS \
|| BX_PLATFORM_WINRT \
|| BX_PLATFORM_XBOXONE \
)
+///
+#define BX_PLATFORM_OS_CONSOLE (0 \
+ || BX_PLATFORM_NX \
+ || BX_PLATFORM_PS4 \
+ || BX_PLATFORM_PS5 \
+ || BX_PLATFORM_WINRT \
+ || BX_PLATFORM_XBOXONE \
+ )
+
+///
+#define BX_PLATFORM_OS_DESKTOP (0 \
+ || BX_PLATFORM_BSD \
+ || BX_PLATFORM_HAIKU \
+ || BX_PLATFORM_HURD \
+ || BX_PLATFORM_LINUX \
+ || BX_PLATFORM_OSX \
+ || BX_PLATFORM_WINDOWS \
+ )
+
+///
+#define BX_PLATFORM_OS_EMBEDDED (0 \
+ || BX_PLATFORM_RPI \
+ )
+
+///
+#define BX_PLATFORM_OS_MOBILE (0 \
+ || BX_PLATFORM_ANDROID \
+ || BX_PLATFORM_IOS \
+ )
+
+///
+#define BX_PLATFORM_OS_WEB (0 \
+ || BX_PLATFORM_EMSCRIPTEN \
+ )
+
+///
#if BX_COMPILER_GCC
# define BX_COMPILER_NAME "GCC " \
BX_STRINGIZE(__GNUC__) "." \
@@ -288,7 +343,11 @@
BX_STRINGIZE(__clang_minor__) "." \
BX_STRINGIZE(__clang_patchlevel__)
#elif BX_COMPILER_MSVC
-# if BX_COMPILER_MSVC >= 1910 // Visual Studio 2017
+# if BX_COMPILER_MSVC >= 1930 // Visual Studio 2022
+# define BX_COMPILER_NAME "MSVC 17.0"
+# elif BX_COMPILER_MSVC >= 1920 // Visual Studio 2019
+# define BX_COMPILER_NAME "MSVC 16.0"
+# elif BX_COMPILER_MSVC >= 1910 // Visual Studio 2017
# define BX_COMPILER_NAME "MSVC 15.0"
# elif BX_COMPILER_MSVC >= 1900 // Visual Studio 2015
# define BX_COMPILER_NAME "MSVC 14.0"
@@ -315,6 +374,8 @@
BX_STRINGIZE(__EMSCRIPTEN_major__) "." \
BX_STRINGIZE(__EMSCRIPTEN_minor__) "." \
BX_STRINGIZE(__EMSCRIPTEN_tiny__)
+#elif BX_PLATFORM_HAIKU
+# define BX_PLATFORM_NAME "Haiku"
#elif BX_PLATFORM_HURD
# define BX_PLATFORM_NAME "Hurd"
#elif BX_PLATFORM_IOS
@@ -329,10 +390,10 @@
# define BX_PLATFORM_NAME "OSX"
#elif BX_PLATFORM_PS4
# define BX_PLATFORM_NAME "PlayStation 4"
+#elif BX_PLATFORM_PS5
+# define BX_PLATFORM_NAME "PlayStation 5"
#elif BX_PLATFORM_RPI
# define BX_PLATFORM_NAME "RaspberryPi"
-#elif BX_PLATFORM_STEAMLINK
-# define BX_PLATFORM_NAME "SteamLink"
#elif BX_PLATFORM_WINDOWS
# define BX_PLATFORM_NAME "Windows"
#elif BX_PLATFORM_WINRT
@@ -359,6 +420,8 @@
#if BX_CRT_BIONIC
# define BX_CRT_NAME "Bionic libc"
+#elif BX_CRT_BSD
+# define BX_CRT_NAME "BSD libc"
#elif BX_CRT_GLIBC
# define BX_CRT_NAME "GNU C Library"
#elif BX_CRT_MSVC
@@ -369,8 +432,6 @@
# define BX_CRT_NAME "Clang C Library"
#elif BX_CRT_NEWLIB
# define BX_CRT_NAME "Newlib"
-#elif BX_CRT_MUSL
-# define BX_CRT_NAME "musl libc"
#elif BX_CRT_NONE
# define BX_CRT_NAME "None"
#else
@@ -383,4 +444,21 @@
# define BX_ARCH_NAME "64-bit"
#endif // BX_ARCH_
+#if defined(__cplusplus)
+# if __cplusplus < BX_LANGUAGE_CPP14
+# error "C++14 standard support is required to build."
+# elif __cplusplus < BX_LANGUAGE_CPP17
+# define BX_CPP_NAME "C++14"
+# elif __cplusplus < BX_LANGUAGE_CPP20
+# define BX_CPP_NAME "C++17"
+# elif __cplusplus < BX_LANGUAGE_CPP23
+# define BX_CPP_NAME "C++20"
+# else
+// See: https://gist.github.com/bkaradzic/2e39896bc7d8c34e042b#orthodox-c
+# define BX_CPP_NAME "C++WayTooModern"
+# endif // BX_CPP_NAME
+#else
+# define BX_CPP_NAME "C++Unknown"
+#endif // defined(__cplusplus)
+
#endif // BX_PLATFORM_H_HEADER_GUARD
diff --git a/3rdparty/bx/include/bx/process.h b/3rdparty/bx/include/bx/process.h
index 8369829527b..e963b90e309 100644
--- a/3rdparty/bx/include/bx/process.h
+++ b/3rdparty/bx/include/bx/process.h
@@ -1,6 +1,6 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_PROCESS_H_HEADER_GUARD
diff --git a/3rdparty/bx/include/bx/readerwriter.h b/3rdparty/bx/include/bx/readerwriter.h
index 0d8e13545a8..01e1d1ca2a8 100644
--- a/3rdparty/bx/include/bx/readerwriter.h
+++ b/3rdparty/bx/include/bx/readerwriter.h
@@ -1,6 +1,6 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_READERWRITER_H_HEADER_GUARD
@@ -10,105 +10,128 @@
#include "endian.h"
#include "error.h"
#include "filepath.h"
+#include "math.h"
#include "string.h"
#include "uint32_t.h"
-BX_ERROR_RESULT(BX_ERROR_READERWRITER_OPEN, BX_MAKEFOURCC('R', 'W', 0, 1) );
-BX_ERROR_RESULT(BX_ERROR_READERWRITER_READ, BX_MAKEFOURCC('R', 'W', 0, 2) );
-BX_ERROR_RESULT(BX_ERROR_READERWRITER_WRITE, BX_MAKEFOURCC('R', 'W', 0, 3) );
-BX_ERROR_RESULT(BX_ERROR_READERWRITER_EOF, BX_MAKEFOURCC('R', 'W', 0, 4) );
-BX_ERROR_RESULT(BX_ERROR_READERWRITER_ALREADY_OPEN, BX_MAKEFOURCC('R', 'W', 0, 5) );
-
namespace bx
{
- ///
+ BX_ERROR_RESULT(kErrorReaderWriterOpen, BX_MAKEFOURCC('b', 'x', 2, 1) );
+ BX_ERROR_RESULT(kErrorReaderWriterRead, BX_MAKEFOURCC('b', 'x', 2, 2) );
+ BX_ERROR_RESULT(kErrorReaderWriterWrite, BX_MAKEFOURCC('b', 'x', 2, 3) );
+ BX_ERROR_RESULT(kErrorReaderWriterEof, BX_MAKEFOURCC('b', 'x', 2, 4) );
+ BX_ERROR_RESULT(kErrorReaderWriterAlreadyOpen, BX_MAKEFOURCC('b', 'x', 2, 5) );
+
+ /// The position from where offset is added.
struct Whence
{
+ /// Whence values:
enum Enum
{
- Begin,
- Current,
- End,
+ Begin, //!< From beginning of file.
+ Current, //!< From current position of file.
+ End, //!< From end of file.
};
};
- ///
+ /// Reader interface.
struct BX_NO_VTABLE ReaderI
{
+ ///
virtual ~ReaderI() = 0;
+
+ ///
virtual int32_t read(void* _data, int32_t _size, Error* _err) = 0;
};
- ///
+ /// Writer interface.
struct BX_NO_VTABLE WriterI
{
+ ///
virtual ~WriterI() = 0;
+
+ ///
virtual int32_t write(const void* _data, int32_t _size, Error* _err) = 0;
};
- ///
+ /// Seeker interface.
struct BX_NO_VTABLE SeekerI
{
+ ///
virtual ~SeekerI() = 0;
+
+ ///
virtual int64_t seek(int64_t _offset = 0, Whence::Enum _whence = Whence::Current) = 0;
};
- ///
+ /// Reader seeker interface.
struct BX_NO_VTABLE ReaderSeekerI : public ReaderI, public SeekerI
{
};
- ///
+ /// Writer seeker interface.
struct BX_NO_VTABLE WriterSeekerI : public WriterI, public SeekerI
{
};
- ///
+ /// Open for reading interface.
struct BX_NO_VTABLE ReaderOpenI
{
+ ///
virtual ~ReaderOpenI() = 0;
- virtual bool open(const FilePath& _filePath, Error* _err) = 0;
+
+ ///
+ virtual bool open(const FilePath& _filePath, Error* _err = ErrorIgnore{}) = 0;
};
- ///
+ /// Open for writing interface.
struct BX_NO_VTABLE WriterOpenI
{
+ ///
virtual ~WriterOpenI() = 0;
- virtual bool open(const FilePath& _filePath, bool _append, Error* _err) = 0;
+
+ ///
+ virtual bool open(const FilePath& _filePath, bool _append = false, Error* _err = ErrorIgnore{}) = 0;
};
- ///
+ /// Open process interface.
struct BX_NO_VTABLE ProcessOpenI
{
+ ///
virtual ~ProcessOpenI() = 0;
- virtual bool open(const FilePath& _filePath, const StringView& _args, Error* _err) = 0;
+
+ ///
+ virtual bool open(const FilePath& _filePath, const StringView& _args, Error* _err = ErrorIgnore{}) = 0;
};
- ///
+ /// Closer interface.
struct BX_NO_VTABLE CloserI
{
+ ///
virtual ~CloserI() = 0;
+
+ ///
virtual void close() = 0;
};
- ///
+ /// File reader interface.
struct BX_NO_VTABLE FileReaderI : public ReaderOpenI, public CloserI, public ReaderSeekerI
{
};
- ///
+ /// File writer interface.
struct BX_NO_VTABLE FileWriterI : public WriterOpenI, public CloserI, public WriterSeekerI
{
};
- ///
+ /// Memory block interface.
struct BX_NO_VTABLE MemoryBlockI
{
virtual void* more(uint32_t _size = 0) = 0;
virtual uint32_t getSize() = 0;
};
- ///
+ /// Static memory block interface.
class StaticMemoryBlock : public MemoryBlockI
{
public:
@@ -125,11 +148,11 @@ namespace bx
virtual uint32_t getSize() override;
private:
- void* m_data;
+ void* m_data;
uint32_t m_size;
};
- ///
+ /// Memory block.
class MemoryBlock : public MemoryBlockI
{
public:
@@ -147,11 +170,11 @@ namespace bx
private:
AllocatorI* m_allocator;
- void* m_data;
- uint32_t m_size;
+ void* m_data;
+ uint32_t m_size;
};
- /// Sizer writer. Dummy writter that only counts number of bytes written into it.
+ /// Sizer writer. Dummy writer that only counts number of bytes written into it.
class SizerWriter : public WriterSeekerI
{
public:
@@ -172,7 +195,7 @@ namespace bx
int64_t m_top;
};
- ///
+ /// Memory reader.
class MemoryReader : public ReaderSeekerI
{
public:
@@ -203,7 +226,7 @@ namespace bx
int64_t m_top;
};
- ///
+ /// Memory writer.
class MemoryWriter : public WriterSeekerI
{
public:
@@ -222,9 +245,9 @@ namespace bx
private:
MemoryBlockI* m_memBlock;
uint8_t* m_data;
- int64_t m_pos;
- int64_t m_top;
- int64_t m_size;
+ int64_t m_pos;
+ int64_t m_top;
+ int64_t m_size;
};
/// Static (fixed size) memory block writer.
@@ -242,49 +265,49 @@ namespace bx
};
/// Read data.
- int32_t read(ReaderI* _reader, void* _data, int32_t _size, Error* _err = NULL);
+ int32_t read(ReaderI* _reader, void* _data, int32_t _size, Error* _err);
/// Read value.
template<typename Ty>
- int32_t read(ReaderI* _reader, Ty& _value, Error* _err = NULL);
+ int32_t read(ReaderI* _reader, Ty& _value, Error* _err);
- /// Read value and converts it to host endianess. _fromLittleEndian specifies
- /// underlying stream endianess.
+ /// Read value and converts it to host endianness. _fromLittleEndian specifies
+ /// underlying stream endianness.
template<typename Ty>
- int32_t readHE(ReaderI* _reader, Ty& _value, bool _fromLittleEndian, Error* _err = NULL);
+ int32_t readHE(ReaderI* _reader, Ty& _value, bool _fromLittleEndian, Error* _err);
/// Write data.
- int32_t write(WriterI* _writer, const void* _data, int32_t _size, Error* _err = NULL);
+ int32_t write(WriterI* _writer, const void* _data, int32_t _size, Error* _err);
/// Write C string.
- int32_t write(WriterI* _writer, const char* _str, Error* _err = NULL);
+ int32_t write(WriterI* _writer, const char* _str, Error* _err);
/// Write string view.
- int32_t write(WriterI* _writer, const StringView& _str, Error* _err = NULL);
+ int32_t write(WriterI* _writer, const StringView& _str, Error* _err);
- /// Write formated string.
+ /// Write formatted string.
int32_t write(WriterI* _writer, const StringView& _format, va_list _argList, Error* _err);
- /// Write formated string.
+ /// Write formatted string.
int32_t write(WriterI* _writer, Error* _err, const StringView* _format, ...);
- /// Write formated string.
+ /// Write formatted string.
int32_t write(WriterI* _writer, Error* _err, const char* _format, ...);
/// Write repeat the same value.
- int32_t writeRep(WriterI* _writer, uint8_t _byte, int32_t _size, Error* _err = NULL);
+ int32_t writeRep(WriterI* _writer, uint8_t _byte, int32_t _size, Error* _err);
/// Write value.
template<typename Ty>
- int32_t write(WriterI* _writer, const Ty& _value, Error* _err = NULL);
+ int32_t write(WriterI* _writer, const Ty& _value, Error* _err);
/// Write value as little endian.
template<typename Ty>
- int32_t writeLE(WriterI* _writer, const Ty& _value, Error* _err = NULL);
+ int32_t writeLE(WriterI* _writer, const Ty& _value, Error* _err);
/// Write value as big endian.
template<typename Ty>
- int32_t writeBE(WriterI* _writer, const Ty& _value, Error* _err = NULL);
+ int32_t writeBE(WriterI* _writer, const Ty& _value, Error* _err);
/// Skip _offset bytes forward.
int64_t skip(SeekerI* _seeker, int64_t _offset);
@@ -299,26 +322,26 @@ namespace bx
int64_t getRemain(SeekerI* _seeker);
/// Peek data.
- int32_t peek(ReaderSeekerI* _reader, void* _data, int32_t _size, Error* _err = NULL);
+ int32_t peek(ReaderSeekerI* _reader, void* _data, int32_t _size, Error* _err);
/// Peek value.
template<typename Ty>
- int32_t peek(ReaderSeekerI* _reader, Ty& _value, Error* _err = NULL);
+ int32_t peek(ReaderSeekerI* _reader, Ty& _value, Error* _err);
/// Align reader stream.
- int32_t align(ReaderSeekerI* _reader, uint32_t _alignment, Error* _err = NULL);
+ int32_t align(ReaderSeekerI* _reader, uint32_t _alignment, Error* _err);
/// Align writer stream (pads stream with zeros).
- int32_t align(WriterSeekerI* _writer, uint32_t _alignment, Error* _err = NULL);
+ int32_t align(WriterSeekerI* _writer, uint32_t _alignment, Error* _err);
/// Open for read.
- bool open(ReaderOpenI* _reader, const FilePath& _filePath, Error* _err = NULL);
+ bool open(ReaderOpenI* _reader, const FilePath& _filePath, Error* _err = ErrorIgnore{});
- /// Open fro write.
- bool open(WriterOpenI* _writer, const FilePath& _filePath, bool _append = false, Error* _err = NULL);
+ /// Open for write.
+ bool open(WriterOpenI* _writer, const FilePath& _filePath, bool _append = false, Error* _err = ErrorIgnore{});
/// Open process.
- bool open(ProcessOpenI* _process, const FilePath& _filePath, const StringView& _args, Error* _err = NULL);
+ bool open(ProcessOpenI* _process, const FilePath& _filePath, const StringView& _args, Error* _err = ErrorIgnore{});
/// Close.
void close(CloserI* _reader);
diff --git a/3rdparty/bx/include/bx/ringbuffer.h b/3rdparty/bx/include/bx/ringbuffer.h
index db44da8432e..84eefddc85f 100644
--- a/3rdparty/bx/include/bx/ringbuffer.h
+++ b/3rdparty/bx/include/bx/ringbuffer.h
@@ -1,6 +1,6 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_RINGBUFFER_H_HEADER_GUARD
@@ -16,8 +16,8 @@ namespace bx
class RingBufferControl
{
BX_CLASS(RingBufferControl
+ , NO_DEFAULT_CTOR
, NO_COPY
- , NO_ASSIGNMENT
);
public:
@@ -55,8 +55,8 @@ namespace bx
class SpScRingBufferControl
{
BX_CLASS(SpScRingBufferControl
+ , NO_DEFAULT_CTOR
, NO_COPY
- , NO_ASSIGNMENT
);
public:
@@ -97,7 +97,6 @@ namespace bx
BX_CLASS(ReadRingBufferT
, NO_DEFAULT_CTOR
, NO_COPY
- , NO_ASSIGNMENT
);
public:
@@ -140,7 +139,6 @@ namespace bx
BX_CLASS(WriteRingBufferT
, NO_DEFAULT_CTOR
, NO_COPY
- , NO_ASSIGNMENT
);
public:
diff --git a/3rdparty/bx/include/bx/rng.h b/3rdparty/bx/include/bx/rng.h
index 87ba511e513..0266eff8326 100644
--- a/3rdparty/bx/include/bx/rng.h
+++ b/3rdparty/bx/include/bx/rng.h
@@ -1,6 +1,6 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_RNG_H_HEADER_GUARD
@@ -67,9 +67,7 @@ namespace bx
template <typename Ty>
bx::Vec3 randUnitHemisphere(Ty* _rng, const bx::Vec3& _normal);
- /// Sampling with Hammersley and Halton Points
- /// http://www.cse.cuhk.edu.hk/~ttwong/papers/udpoint/udpoints.html
- ///
+ /// Sampling with Hammersley and Halton Points.
void generateSphereHammersley(void* _data, uint32_t _stride, uint32_t _num, float _scale = 1.0f);
/// Fisher-Yates shuffle.
diff --git a/3rdparty/bx/include/bx/semaphore.h b/3rdparty/bx/include/bx/semaphore.h
index 6d944ed2919..7748bc8e289 100644
--- a/3rdparty/bx/include/bx/semaphore.h
+++ b/3rdparty/bx/include/bx/semaphore.h
@@ -1,6 +1,6 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_SEM_H_HEADER_GUARD
@@ -15,7 +15,6 @@ namespace bx
{
BX_CLASS(Semaphore
, NO_COPY
- , NO_ASSIGNMENT
);
public:
diff --git a/3rdparty/bx/include/bx/settings.h b/3rdparty/bx/include/bx/settings.h
index 7797cfac2bf..76e4fc3901d 100644
--- a/3rdparty/bx/include/bx/settings.h
+++ b/3rdparty/bx/include/bx/settings.h
@@ -1,6 +1,6 @@
/*
- * Copyright 2011-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2011-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_SETTINGS_H_HEADER_GUARD
@@ -51,10 +51,10 @@ namespace bx
};
///
- int32_t read(ReaderSeekerI* _reader, Settings& _settings, Error* _err = NULL);
+ int32_t read(ReaderSeekerI* _reader, Settings& _settings, Error* _err);
///
- int32_t write(WriterI* _writer, const Settings& _settings, Error* _err = NULL);
+ int32_t write(WriterI* _writer, const Settings& _settings, Error* _err);
} // namespace bx
diff --git a/3rdparty/bx/include/bx/simd_t.h b/3rdparty/bx/include/bx/simd_t.h
index 33c3f48a954..f2be8f6d0ae 100644
--- a/3rdparty/bx/include/bx/simd_t.h
+++ b/3rdparty/bx/include/bx/simd_t.h
@@ -1,6 +1,6 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_SIMD_T_H_HEADER_GUARD
@@ -32,7 +32,7 @@
# include <xmmintrin.h> // __m128
# undef BX_SIMD_SSE
# define BX_SIMD_SSE 1
-#elif defined(__ARM_NEON__) && !BX_COMPILER_CLANG
+#elif defined(__ARM_NEON__) && (!BX_COMPILER_CLANG || BX_CLANG_HAS_EXTENSION(attribute_ext_vector_type) )
# include <arm_neon.h>
# undef BX_SIMD_NEON
# define BX_SIMD_NEON 1
@@ -197,6 +197,9 @@ BX_SIMD128_IMPLEMENT_TEST(xyzw);
Ty simd_cmpeq(Ty _a, Ty _b);
template<typename Ty>
+ Ty simd_cmpneq(Ty _a, Ty _b);
+
+ template<typename Ty>
Ty simd_cmplt(Ty _a, Ty _b);
template<typename Ty>
@@ -371,6 +374,9 @@ BX_SIMD128_IMPLEMENT_TEST(xyzw);
Ty simd_not_ni(Ty _a);
template<typename Ty>
+ Ty simd_cmpneq_ni(Ty _a, Ty _b);
+
+ template<typename Ty>
Ty simd_min_ni(Ty _a, Ty _b);
template<typename Ty>
diff --git a/3rdparty/bx/include/bx/sort.h b/3rdparty/bx/include/bx/sort.h
index 1506fb8307b..cee84bfdb63 100644
--- a/3rdparty/bx/include/bx/sort.h
+++ b/3rdparty/bx/include/bx/sort.h
@@ -1,18 +1,52 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_SORT_H_HEADER_GUARD
#define BX_SORT_H_HEADER_GUARD
#include "bx.h"
+#include "math.h"
+#include "string.h"
namespace bx
{
+ /// The function compares the `_lhs` and `_rhs` values.
+ ///
+ /// @returns Returns value:
+ /// - less than zero if `_lhs` is less than `_rhs`
+ /// - zero if `_lhs` is equivalent to `_rhs`
+ /// - greater than zero if `_lhs` is greater than `_rhs`
///
typedef int32_t (*ComparisonFn)(const void* _lhs, const void* _rhs);
+ /// The function compares the `_lhs` and `_rhs` values.
+ ///
+ /// @returns Returns value:
+ /// - less than zero if `_lhs` is less than `_rhs`
+ /// - zero if `_lhs` is equivalent to `_rhs`
+ /// - greater than zero if `_lhs` is greater than `_rhs`
+ ///
+ template<typename Ty>
+ int32_t compareAscending(const void* _lhs, const void* _rhs);
+
+ /// The function compares the `_lhs` and `_rhs` values.
+ ///
+ /// @returns Returns value:
+ /// - less than zero if `_lhs` is greated than `_rhs`
+ /// - zero if `_lhs` is equivalent to `_rhs`
+ /// - greater than zero if `_lhs` is less than `_rhs`
+ ///
+ template<typename Ty>
+ int32_t compareDescending(const void* _lhs, const void* _rhs);
+
+ /// Performs sort (Quick Sort algorithm).
+ ///
+ /// @param _data Pointer to array data.
+ /// @param _num Number of elements.
+ /// @param _stride Element stride in bytes.
+ /// @param _fn Comparison function.
///
void quickSort(
void* _data
@@ -21,6 +55,245 @@ namespace bx
, const ComparisonFn _fn
);
+ /// Performs sort (Quick Sort algorithm).
+ ///
+ /// @param _data Pointer to array data.
+ /// @param _num Number of elements.
+ /// @param _stride Element stride in bytes.
+ /// @param _fn Comparison function.
+ ///
+ template<typename Ty>
+ void quickSort(void* _data, uint32_t _num, uint32_t _stride, const ComparisonFn _fn = compareAscending<Ty>);
+
+ /// Performs sort (Quick Sort algorithm).
+ ///
+ /// @param _data Pointer to array data.
+ /// @param _num Number of elements.
+ /// @param _fn Comparison function.
+ ///
+ template<typename Ty>
+ void quickSort(Ty* _data, uint32_t _num, const ComparisonFn _fn = compareAscending<Ty>);
+
+ /// Performs reordering of duplicate elements in the array in the way that unique elements
+ /// are sorted to the front of array, and duplicates are after the return value index.
+ ///
+ /// @param _data Pointer to sorted array data.
+ /// @param _num Number of elements.
+ /// @param _stride Element stride in bytes.
+ /// @param _fn Comparison function.
+ ///
+ /// @remarks Array must be sorted!
+ ///
+ /// @returns Returns the count of unique elements.
+ ///
+ uint32_t unique(void* _data, uint32_t _num, uint32_t _stride, const ComparisonFn _fn);
+
+ /// Performs reordering of duplicate elements in the array in the way that unique elements
+ /// are sorted to the front of array, and duplicates are after the return value index.
+ ///
+ /// @param _data Pointer to sorted array data.
+ /// @param _num Number of elements.
+ /// @param _stride Element stride in bytes.
+ /// @param _fn Comparison function.
+ ///
+ /// @remarks Array must be sorted!
+ ///
+ /// @returns Returns the count of unique elements.
+ ///
+ template<typename Ty>
+ uint32_t unique(void* _data, uint32_t _num, uint32_t _stride, const ComparisonFn _fn = compareAscending<Ty>);
+
+ /// Performs reordering of duplicate elements in the array in the way that unique elements
+ /// are sorted to the front of array, and duplicates are after the return value index.
+ ///
+ /// @param _data Pointer to sorted array data.
+ /// @param _num Number of elements.
+ /// @param _fn Comparison function.
+ ///
+ /// @remarks Array must be sorted!
+ ///
+ /// @returns Returns the count of unique elements.
+ ///
+ template<typename Ty>
+ uint32_t unique(Ty* _data, uint32_t _num, const ComparisonFn _fn = compareAscending<Ty>);
+
+ /// Performs check if array is sorted.
+ ///
+ /// @param _data Pointer to sorted array data.
+ /// @param _num Number of elements.
+ /// @param _stride Element stride in bytes.
+ /// @param _fn Comparison function.
+ ///
+ /// @returns Returns `true` if array is sorted, otherwise returns `false`.
+ ///
+ bool isSorted(
+ const void* _data
+ , uint32_t _num
+ , uint32_t _stride
+ , const ComparisonFn _fn
+ );
+
+ /// Performs check if array is sorted.
+ ///
+ /// @param _data Pointer to sorted array data.
+ /// @param _num Number of elements.
+ /// @param _stride Element stride in bytes.
+ /// @param _fn Comparison function.
+ ///
+ /// @returns Returns `true` if array is sorted, otherwise returns `false`.
+ ///
+ template<typename Ty>
+ bool isSorted(const void* _data, uint32_t _num, uint32_t _stride, const ComparisonFn _fn = compareAscending<Ty>);
+
+ /// Performs check if array is sorted.
+ ///
+ /// @param _data Pointer to sorted array data.
+ /// @param _num Number of elements.
+ /// @param _fn Comparison function.
+ ///
+ /// @returns Returns `true` if array is sorted, otherwise returns `false`.
+ ///
+ template<typename Ty>
+ bool isSorted(const Ty* _data, uint32_t _num, const ComparisonFn _fn = compareAscending<Ty>);
+
+ /// Returns an index to the first element greater or equal than the `_key` value.
+ ///
+ /// @param _key Pointer to the key to search for.
+ /// @param _data Pointer to sorted array data.
+ /// @param _num Number of elements.
+ /// @param _stride Element stride in bytes.
+ /// @param _fn Comparison function.
+ ///
+ /// @remarks Array must be sorted!
+ ///
+ /// @returns Returns an index to the first element greater or equal than the `_key` value.
+ ///
+ uint32_t lowerBound(const void* _key, const void* _data, uint32_t _num, uint32_t _stride, const ComparisonFn _fn);
+
+ /// Returns an index to the first element greater or equal than the `_key` value.
+ ///
+ /// @param _key Pointer to the key to search for.
+ /// @param _data Pointer to sorted array data.
+ /// @param _num Number of elements.
+ /// @param _fn Comparison function.
+ ///
+ /// @remarks Array must be sorted!
+ ///
+ /// @returns Returns an index to the first element greater or equal than the `_key` value.
+ ///
+ template<typename Ty>
+ uint32_t lowerBound(const Ty& _key, const Ty* _data, uint32_t _num, const ComparisonFn _fn = compareAscending<Ty>);
+
+ /// Returns an index to the first element greater or equal than the `_key` value.
+ ///
+ /// @param _key Pointer to the key to search for.
+ /// @param _data Pointer to sorted array data.
+ /// @param _num Number of elements.
+ /// @param _stride Element stride in bytes.
+ /// @param _fn Comparison function.
+ ///
+ /// @remarks Array must be sorted!
+ ///
+ /// @returns Returns an index to the first element greater or equal than the `_key` value.
+ ///
+ template<typename Ty>
+ uint32_t lowerBound(const Ty& _key, const void* _data, uint32_t _num, uint32_t _stride, const ComparisonFn _fn = compareAscending<Ty>);
+
+ /// Returns an index to the first element greater than the `_key` value.
+ ///
+ /// @param _key Pointer to the key to search for.
+ /// @param _data Pointer to sorted array data.
+ /// @param _num Number of elements.
+ /// @param _stride Element stride in bytes.
+ /// @param _fn Comparison function.
+ ///
+ /// @remarks Array must be sorted!
+ ///
+ /// @returns Returns an index to the first element greater than the `_key` value.
+ ///
+ uint32_t upperBound(const void* _key, const void* _data, uint32_t _num, uint32_t _stride, const ComparisonFn _fn);
+
+ /// Returns an index to the first element greater than the `_key` value.
+ ///
+ /// @param _key Pointer to the key to search for.
+ /// @param _data Pointer to sorted array data.
+ /// @param _num Number of elements.
+ /// @param _fn Comparison function.
+ ///
+ /// @remarks Array must be sorted!
+ ///
+ /// @returns Returns an index to the first element greater than the `_key` value.
+ ///
+ template<typename Ty>
+ uint32_t upperBound(const Ty& _key, const Ty* _data, uint32_t _num, const ComparisonFn _fn = compareAscending<Ty>);
+
+ /// Returns an index to the first element greater than the `_key` value.
+ ///
+ /// @param _key Pointer to the key to search for.
+ /// @param _data Pointer to sorted array data.
+ /// @param _num Number of elements.
+ /// @param _stride Element stride in bytes.
+ /// @param _fn Comparison function.
+ ///
+ /// @remarks Array must be sorted!
+ ///
+ /// @returns Returns an index to the first element greater than the `_key` value.
+ ///
+ template<typename Ty>
+ uint32_t upperBound(const Ty& _key, const void* _data, uint32_t _num, uint32_t _stride, const ComparisonFn _fn = compareAscending<Ty>);
+
+ /// Performs binary search of a sorted array.
+ ///
+ /// @param _key Pointer to the key to search for.
+ /// @param _data Pointer to sorted array data.
+ /// @param _num Number of elements.
+ /// @param _stride Element stride in bytes.
+ /// @param _fn Comparison function.
+ ///
+ /// @remarks Array must be sorted!
+ ///
+ /// @returns Returns positive value index of element if found, or negative number that is bitwise
+ /// complement (~) of the index of the next element that's larger than item.
+ ///
+ int32_t binarySearch(
+ const void* _key
+ , const void* _data
+ , uint32_t _num
+ , uint32_t _stride
+ , const ComparisonFn _fn
+ );
+
+ /// Performs binary search of a sorted array.
+ ///
+ /// @param _key Pointer to the key to search for.
+ /// @param _data Pointer to sorted array data.
+ /// @param _num Number of elements.
+ /// @param _fn Comparison function.
+ ///
+ /// @remarks Array must be sorted!
+ ///
+ /// @returns Returns positive value index of element if found, or negative number that is bitwise
+ /// complement (~) of the index of the next element that's larger than item.
+ ///
+ template<typename Ty>
+ int32_t binarySearch(const Ty& _key, const Ty* _data, uint32_t _num, const ComparisonFn _fn = compareAscending<Ty>);
+
+ /// Performs binary search of a sorted array.
+ ///
+ /// @param _key Pointer to the key to search for.
+ /// @param _data Pointer to sorted array data.
+ /// @param _num Number of elements.
+ /// @param _stride Element stride in bytes.
+ /// @param _fn Comparison function.
+ ///
+ /// @remarks Array must be sorted!
+ ///
+ /// @returns Returns positive value index of element if found, or negative number that is bitwise
+ /// complement (~) of the index of the next element that's larger than item.
+ ///
+ template<typename Ty>
+ int32_t binarySearch(const Ty& _key, const void* _data, uint32_t _num, uint32_t _stride = sizeof(Ty), const ComparisonFn _fn = compareAscending<Ty>);
+
///
void radixSort(
uint32_t* _keys
diff --git a/3rdparty/bx/include/bx/spscqueue.h b/3rdparty/bx/include/bx/spscqueue.h
index f34b65dfada..eaa8cd23b91 100644
--- a/3rdparty/bx/include/bx/spscqueue.h
+++ b/3rdparty/bx/include/bx/spscqueue.h
@@ -1,6 +1,6 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_SPSCQUEUE_H_HEADER_GUARD
@@ -16,8 +16,8 @@ namespace bx
class SpScUnboundedQueue
{
BX_CLASS(SpScUnboundedQueue
+ , NO_DEFAULT_CTOR
, NO_COPY
- , NO_ASSIGNMENT
);
public:
@@ -57,8 +57,8 @@ namespace bx
class SpScUnboundedQueueT
{
BX_CLASS(SpScUnboundedQueueT
+ , NO_DEFAULT_CTOR
, NO_COPY
- , NO_ASSIGNMENT
);
public:
@@ -86,8 +86,8 @@ namespace bx
class SpScBlockingUnboundedQueue
{
BX_CLASS(SpScBlockingUnboundedQueue
+ , NO_DEFAULT_CTOR
, NO_COPY
- , NO_ASSIGNMENT
);
public:
@@ -116,8 +116,8 @@ namespace bx
class SpScBlockingUnboundedQueueT
{
BX_CLASS(SpScBlockingUnboundedQueueT
+ , NO_DEFAULT_CTOR
, NO_COPY
- , NO_ASSIGNMENT
);
public:
diff --git a/3rdparty/bx/include/bx/string.h b/3rdparty/bx/include/bx/string.h
index e0800562d71..d6629dc31eb 100644
--- a/3rdparty/bx/include/bx/string.h
+++ b/3rdparty/bx/include/bx/string.h
@@ -1,6 +1,6 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_STRING_H_HEADER_GUARD
@@ -21,6 +21,7 @@ namespace bx
};
/// Non-zero-terminated string view.
+ ///
class StringView
{
public:
@@ -37,28 +38,15 @@ namespace bx
StringView& operator=(const StringView& _rhs);
///
- StringView(char* _ptr);
-
- ///
StringView(const char* _ptr);
///
- StringView(char* _ptr, int32_t _len);
-
- ///
StringView(const char* _ptr, int32_t _len);
///
StringView(const char* _ptr, const char* _term);
///
- template<typename Ty>
- explicit StringView(const Ty& _container);
-
- ///
- void set(char* _ptr);
-
- ///
void set(const char* _ptr);
///
@@ -71,27 +59,34 @@ namespace bx
void set(const StringView& _str, int32_t _start = 0, int32_t _len = INT32_MAX);
///
- template<typename Ty>
- void set(const Ty& _container);
-
- ///
void clear();
+ /// Returns pointer to non-terminated string.
+ ///
+ /// @attention Use of this pointer in standard C/C++ functions is not safe. You must use it
+ /// in conjunction with `getTerm()` or getLength()`.
///
const char* getPtr() const;
+ /// Returns pointer past last character in string view.
+ ///
+ /// @attention Dereferencing this pointer is not safe.
///
const char* getTerm() const;
- ///
+ /// Returns `true` if string is empty.
bool isEmpty() const;
- ///
+ /// Returns string length.
int32_t getLength() const;
+ /// Returns `true` if string is zero terminated.
+ bool is0Terminated() const;
+
protected:
const char* m_ptr;
int32_t m_len;
+ bool m_0terminated;
};
/// ASCII string
@@ -106,37 +101,47 @@ namespace bx
StringT(const StringT<AllocatorT>& _rhs);
///
- StringT<AllocatorT>& operator=(const StringT<AllocatorT>& _rhs);
-
- ///
StringT(const StringView& _rhs);
///
~StringT();
///
+ StringT<AllocatorT>& operator=(const StringT<AllocatorT>& _rhs);
+
+ ///
void set(const StringView& _str);
///
void append(const StringView& _str);
///
+ void append(const char* _ptr, const char* _term);
+
+ ///
void clear();
+
+ /// Returns zero-terminated C string pointer.
+ ///
+ const char* getCPtr() const;
+
+ protected:
+ int32_t m_capacity;
};
- /// Retruns true if character is part of space set.
+ /// Returns true if character is part of space set.
bool isSpace(char _ch);
/// Returns true if string view contains only space characters.
bool isSpace(const StringView& _str);
- /// Retruns true if character is uppercase.
+ /// Returns true if character is uppercase.
bool isUpper(char _ch);
/// Returns true if string view contains only uppercase characters.
bool isUpper(const StringView& _str);
- /// Retruns true if character is lowercase.
+ /// Returns true if character is lowercase.
bool isLower(char _ch);
/// Returns true if string view contains only lowercase characters.
@@ -145,19 +150,19 @@ namespace bx
/// Returns true if character is part of alphabet set.
bool isAlpha(char _ch);
- /// Retruns true if string view contains only alphabet characters.
+ /// Returns true if string view contains only alphabet characters.
bool isAlpha(const StringView& _str);
/// Returns true if character is part of numeric set.
bool isNumeric(char _ch);
- /// Retruns true if string view contains only numeric characters.
+ /// Returns true if string view contains only numeric characters.
bool isNumeric(const StringView& _str);
/// Returns true if character is part of alpha numeric set.
bool isAlphaNum(char _ch);
- /// Returns true if string view contains only alpha-numeric characters.
+ /// Returns true if string view contains only alphanumeric characters.
bool isAlphaNum(const StringView& _str);
/// Returns true if character is part of hexadecimal set.
@@ -172,7 +177,7 @@ namespace bx
/// Returns true if string vieww contains only printable characters.
bool isPrint(const StringView& _str);
- /// Retruns lower case character representing _ch.
+ /// Returns lower case character representing _ch.
char toLower(char _ch);
/// Lower case string in place assuming length passed is valid.
@@ -209,9 +214,15 @@ namespace bx
/// including zero terminator. Copy will be terminated with '\0'.
int32_t strCopy(char* _dst, int32_t _dstSize, const StringView& _str, int32_t _num = INT32_MAX);
- /// Concatinate string.
+ /// Concatenate string.
int32_t strCat(char* _dst, int32_t _dstSize, const StringView& _str, int32_t _num = INT32_MAX);
+ /// Test whether the string _str begins with prefix.
+ bool hasPrefix(const StringView& _str, const StringView& _prefix);
+
+ /// Test whether the string _str ends with suffix.
+ bool hasSuffix(const StringView& _str, const StringView& _suffix);
+
/// Find character in string. Limit search to _max characters.
StringView strFind(const StringView& _str, char _ch);
@@ -236,13 +247,25 @@ namespace bx
/// Returns string view with characters _chars trimmed from right.
StringView strRTrim(const StringView& _str, const StringView& _chars);
+ /// Returns string view with whitespace characters trimmed from right.
+ StringView strRTrimSpace(const StringView& _str);
+
/// Returns string view with characters _chars trimmed from left and right.
StringView strTrim(const StringView& _str, const StringView& _chars);
+ /// Returns string view with whitespace characters trimmed from left and right.
+ StringView strTrimSpace(const StringView& _str);
+
+ /// Returns string view with prefix trimmed.
+ StringView strTrimPrefix(const StringView& _str, const StringView& _prefix);
+
+ /// Returns string view with suffix trimmed.
+ StringView strTrimSuffix(const StringView& _str, const StringView& _suffix);
+
/// Find new line. Returns pointer after new line terminator.
StringView strFindNl(const StringView& _str);
- /// Find end of line. Retuns pointer to new line terminator.
+ /// Find end of line. Returns pointer to new line terminator.
StringView strFindEol(const StringView& _str);
/// Returns StringView of word or empty.
@@ -261,7 +284,7 @@ namespace bx
StringView findIdentifierMatch(const StringView& _str, const StringView& _word);
/// Finds any identifier from NULL terminated array of identifiers.
- StringView findIdentifierMatch(const StringView& _str, const char** _words);
+ StringView findIdentifierMatch(const StringView& _str, const char** _words, int32_t _num = INT32_MAX);
/// Cross platform implementation of vsnprintf that returns number of
/// characters which would have been written to the final string if
@@ -273,6 +296,12 @@ namespace bx
/// enough space had been available.
int32_t snprintf(char* _out, int32_t _max, const char* _format, ...);
+ ///
+ int32_t vprintf(const char* _format, va_list _argList);
+
+ ///
+ int32_t printf(const char* _format, ...);
+
/// Templatized snprintf.
template <typename Ty>
void stringPrintfVargs(Ty& _out, const char* _format, va_list _argList);
@@ -281,10 +310,6 @@ namespace bx
template <typename Ty>
void stringPrintf(Ty& _out, const char* _format, ...);
- /// Replace all instances of substring.
- template <typename Ty>
- Ty replaceAll(const Ty& _str, const char* _from, const char* _to);
-
/// Convert size in bytes to human readable string kibi units.
int32_t prettify(char* _out, int32_t _count, uint64_t _value, Units::Enum _units = Units::Kibi);
@@ -321,6 +346,31 @@ namespace bx
/// Converts string to 32-bit unsigned integer value.
bool fromString(uint32_t* _out, const StringView& _str);
+ ///
+ class LineReader
+ {
+ public:
+ ///
+ LineReader(const StringView& _str);
+
+ ///
+ void reset();
+
+ ///
+ StringView next();
+
+ ///
+ bool isDone() const;
+
+ ///
+ uint32_t getLine() const;
+
+ private:
+ const StringView m_str;
+ StringView m_curr;
+ uint32_t m_line;
+ };
+
} // namespace bx
#include "inline/string.inl"
diff --git a/3rdparty/bx/include/bx/thread.h b/3rdparty/bx/include/bx/thread.h
index 087bd3d4a57..25a18070b24 100644
--- a/3rdparty/bx/include/bx/thread.h
+++ b/3rdparty/bx/include/bx/thread.h
@@ -1,6 +1,6 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_THREAD_H_HEADER_GUARD
@@ -9,6 +9,8 @@
#include "allocator.h"
#include "mpscqueue.h"
+#if BX_CONFIG_SUPPORTS_THREADING
+
namespace bx
{
///
@@ -19,7 +21,6 @@ namespace bx
{
BX_CLASS(Thread
, NO_COPY
- , NO_ASSIGNMENT
);
public:
@@ -29,8 +30,16 @@ namespace bx
///
virtual ~Thread();
+ /// Create and initialize thread.
+ ///
+ /// @param[in] _fn Thread function.
+ /// @param[in] _userData User data passed to thread function.
+ /// @param[in] _stackSize Stack size, if zero is passed it will use OS default thread stack
+ /// size.
+ /// @param[in] _name Thread name used by debugger.
+ /// @returns True if thread is created, otherwise returns false.
///
- void init(ThreadFn _fn, void* _userData = NULL, uint32_t _stackSize = 0, const char* _name = NULL);
+ bool init(ThreadFn _fn, void* _userData = NULL, uint32_t _stackSize = 0, const char* _name = NULL);
///
void shutdown();
@@ -87,4 +96,6 @@ namespace bx
} // namespace bx
+#endif
+
#endif // BX_THREAD_H_HEADER_GUARD
diff --git a/3rdparty/bx/include/bx/timer.h b/3rdparty/bx/include/bx/timer.h
index b0b0b403a8b..c860777c510 100644
--- a/3rdparty/bx/include/bx/timer.h
+++ b/3rdparty/bx/include/bx/timer.h
@@ -1,6 +1,6 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_TIMER_H_HEADER_GUARD
diff --git a/3rdparty/bx/include/bx/typetraits.h b/3rdparty/bx/include/bx/typetraits.h
new file mode 100644
index 00000000000..9c301f617ea
--- /dev/null
+++ b/3rdparty/bx/include/bx/typetraits.h
@@ -0,0 +1,285 @@
+/*
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
+ */
+
+#ifndef BX_TYPETRAITS_H_HEADER_GUARD
+#define BX_TYPETRAITS_H_HEADER_GUARD
+
+namespace bx
+{
+ /// Returns true if type `Ty` is array type with known bound, otherwise returns false.
+ template<typename Ty>
+ constexpr bool isBoundedArray();
+
+ /// Returns true if type `Ty` is array type with unknown bound, otherwise returns false.
+ template<typename Ty>
+ constexpr bool isUnboundedArray();
+
+ /// Returns true if type `Ty` is array type (bounded, or unbounded array), otherwise returns false.
+ template<typename Ty>
+ constexpr bool isArray();
+
+ /// Returns true if type `Ty` is enumeration type, otherwise returns false.
+ template<typename Ty>
+ constexpr bool isEnum();
+
+ /// Returns true if type `Ty` is union type, otherwise returns false.
+ template<typename Ty>
+ constexpr bool isUnion();
+
+ /// Returns true if type `Ty` is non-union class type, otherwise returns false.
+ template<typename Ty>
+ constexpr bool isClass();
+
+ /// Returns true if type `Ty` is abstract class type, otherwise returns false.
+ template<typename Ty>
+ constexpr bool isAbstract();
+
+ /// Returns true if type `Ty` is aggregate class type, otherwise returns false.
+ template<typename Ty>
+ constexpr bool isAggregate();
+
+ /// Returns true if type `DerivedT` is derived from `BaseT` type, or if both are the same
+ /// non-union type, otherwise returns false.
+ template<typename BaseT, typename DerivedT>
+ constexpr bool isBaseOf();
+
+ /// Returns true if type `Ty` is polymorphic class (if it has virtual function table) type,
+ /// otherwise returns false.
+ template<typename Ty>
+ constexpr bool isPolymorphic();
+
+ /// Returns true if type `Ty` has virtual destructor, otherwise returns false.
+ template<typename Ty>
+ constexpr bool isDestructorVirtual();
+
+ /// Returns true if type `Ty` is class type with final specifier, otherwise returns false.
+ template<typename Ty>
+ constexpr bool isFinal();
+
+ /// Returns true if type `Ty` is non-union class type with no non-static
+ /// members (a.k.a. sizeof(Ty) is zero), otherwise returns false.
+ template<typename Ty>
+ constexpr bool isEmpty();
+
+ /// Returns true if type `Ty` is standard-layout type, otherwise returns false.
+ template<typename Ty>
+ constexpr bool isStandardLayout();
+
+ /// Returns true if type `Ty` is trivial type, otherwise returns false.
+ template<typename Ty>
+ constexpr bool isTrivial();
+
+ /// Returns true if type `Ty` is POD (standard-layout, and trivial type), otherwise returns false.
+ template<typename Ty>
+ constexpr bool isPod();
+
+ /// Returns true if type `FromT` can be assigned to type `Ty`, otherwise returns false.
+ template<typename Ty, typename FromT>
+ constexpr bool isAssignable();
+
+ /// Returns true if type `Ty` has copy assignment operator, otherwise returns false.
+ template<typename Ty, typename Uy>
+ constexpr bool isCopyAssignable();
+
+ /// Returns true if type `Ty` has move assignment operator, otherwise returns false.
+ template<typename Ty, typename Uy>
+ constexpr bool isMoveAssignable();
+
+ /// Returns true if type `FromT` can be trivially assigned to type `Ty`, otherwise returns false.
+ template<typename Ty, typename FromT>
+ constexpr bool isTriviallyAssignable();
+
+ /// Returns true if type `Ty` is trivially copy-assignable type, otherwise returns false.
+ template<typename Ty>
+ constexpr bool isTriviallyCopyAssignable();
+
+ /// Returns true if type `Ty` is trivially move-assignable type, otherwise returns false.
+ template<typename Ty>
+ constexpr bool isTriviallyMoveAssignable();
+
+ /// Returns true if type `Ty` is constructible when the specified argument types are used,
+ /// otherwise returns false.
+ template<typename Ty, typename... ArgsT>
+ constexpr bool isConstructible();
+
+ /// Returns true if type `Ty` has copy constructor, otherwise returns false.
+ template<typename Ty>
+ constexpr bool isCopyConstructible();
+
+ /// Returns true if type `Ty` has move constructor, otherwise returns false.
+ template<typename Ty>
+ constexpr bool isMoveConstructible();
+
+ /// Returns true if type `Ty` is trivially constructible when the specified argument types are used,
+ /// otherwise returns false.
+ template<typename T, typename... ArgsT>
+ constexpr bool isTriviallyConstructible();
+
+ /// Returns true if type `Ty` has trivial copy constructor, otherwise returns false.
+ template<typename Ty>
+ constexpr bool isTriviallyCopyConstructible();
+
+ /// Returns true if type `Ty` has trivial move constructor, otherwise returns false.
+ template<typename Ty>
+ constexpr bool isTriviallyMoveConstructible();
+
+ /// Returns true if type `Ty` is trivially copyable / POD type, otherwise returns false.
+ template<typename Ty>
+ constexpr bool isTriviallyCopyable();
+
+ /// Returns true if type `Ty` has trivial destructor, otherwise returns false.
+ template<typename Ty>
+ constexpr bool isTriviallyDestructible();
+
+ /// Returns true if type `Ty` is const-qualified type, otherwise returns false.
+ template<typename Ty>
+ constexpr bool isConst();
+
+ /// Returns true if type `Ty` is volatile-qualified type, otherwise returns false.
+ template<typename Ty>
+ constexpr bool isVolatile();
+
+ /// Returns true if type `Ty` is an reference type, otherwise returns false.
+ template<typename Ty>
+ constexpr bool isReference();
+
+ /// Returns true if type `Ty` is an Lvalue reference type, otherwise returns false.
+ template<typename Ty>
+ constexpr bool isLvalueReference();
+
+ /// Returns true if type `Ty` is an Rvalue reference type, otherwise returns false.
+ template<typename Ty>
+ constexpr bool isRvalueReference();
+
+ /// Returns true if type `Ty` is an pointer type, otherwise returns false.
+ template<typename Ty>
+ constexpr bool isPointer();
+
+ /// Returns true if type `Ty` is signed integer or floating-point type, otherwise returns false.
+ template<typename Ty>
+ constexpr bool isSigned();
+
+ /// Returns true if type `Ty` is unsigned integer type, otherwise returns false.
+ template<typename Ty>
+ constexpr bool isUnsigned();
+
+ /// Returns true if type `Ty` is integer type, otherwise returns false.
+ template<typename Ty>
+ constexpr bool isInteger();
+
+ /// Returns true if type `Ty` is floating-point type, otherwise returns false.
+ template<typename Ty>
+ constexpr bool isFloatingPoint();
+
+ /// Returns true if type `Ty` is arithmetic type, otherwise returns false.
+ template<typename Ty>
+ constexpr bool isArithmetic();
+
+ /// Returns true if type `Ty` and type `Uy` are the same type, otherwise returns false.
+ template<typename Ty, typename Uy>
+ constexpr bool isSame();
+
+} // namespace bx
+
+#include "inline/typetraits.inl"
+
+namespace bx
+{
+ /// Compile-time constant of specified type `Ty` with specified value `ValueT`.
+ template<typename Ty, Ty ValueT>
+ struct IntegralConstantT;
+
+ /// Alias of IntegralConstantT<bool, bool ValueT>.
+ template<bool BoolT>
+ using BoolConstantT = IntegralConstantT<bool, BoolT>;
+
+ /// Alias of BoolConstantT<bool, false>.
+ using FalseConstant = BoolConstantT<false>;
+
+ /// Alias of BoolConstantT<bool, true>.
+ using TrueConstant = BoolConstantT<true>;
+
+ /// Provides the member `Type` that names `Ty`.
+ template<typename Ty>
+ using TypeIdentityType = typename TypeIdentityT<Ty>::Type;
+
+ /// Conditionally selects `Ty` if `BoolT` is true, otherwise selects `Uy` type.
+ template<bool BoolT, typename Ty, typename Uy>
+ using ConditionalType = typename ConditionalT<BoolT, Ty, Uy>::Type;
+
+ /// If `BoolT` condition is true it provides `Ty` as `Type`, otherwise `Type` is undefined.
+ template<bool BoolT, typename Ty>
+ using EnableIfType = typename EnableIfT<BoolT, Ty>::Type;
+
+ /// If `Ty` is an object type or a function type that has no cv- or ref- qualifier, provides
+ /// a member `Type` which is `Ty&`. If `Ty` is an Rvalue reference to some type `Uy`, then
+ /// type is `Uy&`, otherwise type is `Ty`.
+ template<typename Ty>
+ using AddLvalueReferenceType = typename AddLvalueReferenceT<Ty>::Type;
+
+ /// If `Ty` is an object type or a function type that has no cv- or ref- qualifier, provides
+ /// a member `Type` which is `Ty&&`, otherwise type is `Ty`.
+ template<typename Ty>
+ using AddRvalueReferenceType = typename AddRvalueReferenceT<Ty>::Type;
+
+ /// If the type `Ty` is a reference type, provides the member typedef `Type`
+ /// which is the type referred to by `Ty`, otherwise type is `Ty`.
+ template<typename Ty>
+ using RemoveReferenceType = typename RemoveReferenceT<Ty>::Type;
+
+ /// If the type `Ty` is a reference type, provides the member typedef `Type`
+ /// which is a pointer to the referred type.
+ template<typename Ty>
+ using AddPointerType = typename AddPointerT<Ty>::Type;
+
+ /// If the type `Ty` is a pointer type, provides the member typedef `Type`
+ /// which is the type pointed to by `Ty`, otherwise type is `Ty`.
+ template<typename Ty>
+ using RemovePointerType = typename RemovePointerT<Ty>::Type;
+
+ /// Adds both `const`, and `volatile` to type `Ty`.
+ template<typename Ty>
+ using AddCvType = typename AddCvT<Ty>::Type;
+
+ /// Removes the topmost `const`, or the topmost `volatile`, or both, from type `Ty` if present.
+ template<typename Ty>
+ using RemoveCvType = typename RemoveCvT<Ty>::Type;
+
+ /// Adds `const` to type `Ty`.
+ template<typename Ty>
+ using AddConstType = typename AddConstT<Ty>::Type;
+
+ /// Removes the topmost `const` from type `Ty` if present.
+ template<typename Ty>
+ using RemoveConstType = typename RemoveConstT<Ty>::Type;
+
+ /// Adds `volatile` to type `Ty`.
+ template<typename Ty>
+ using AddVolatileType = typename AddVolatileT<Ty>::Type;
+
+ /// Removes the topmost `volatile` from type `Ty` if present.
+ template<typename Ty>
+ using RemoveVolatileType = typename RemoveVolatileT<Ty>::Type;
+
+ /// Removes reference from type `Ty` if present.
+ template<typename Ty>
+ constexpr RemoveReferenceType<Ty>&& move(Ty&& _a);
+
+ /// Forwards Lvalues as either Lvalues or as Rvalues.
+ template<typename Ty>
+ constexpr Ty&& forward(RemoveReferenceType<Ty>& _type);
+
+ /// Forwards Rvalues as Rvalues and prohibits forwarding of Rvalues as Lvalues.
+ template<typename Ty>
+ constexpr Ty&& forward(RemoveReferenceT<Ty>&& _type);
+
+ /// Converts any type `Ty` to a reference type, making it possible to use member functions
+ /// in decltype expressions without the need to go through constructors.
+ template<typename Ty>
+ AddRvalueReferenceType<Ty> declVal();
+
+} // namespace bx
+
+#endif // BX_TYPETRAITS_H_HEADER_GUARD
diff --git a/3rdparty/bx/include/bx/uint32_t.h b/3rdparty/bx/include/bx/uint32_t.h
index 3d0afcb7124..cff793e0d2c 100644
--- a/3rdparty/bx/include/bx/uint32_t.h
+++ b/3rdparty/bx/include/bx/uint32_t.h
@@ -1,6 +1,6 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_UINT32_T_H_HEADER_GUARD
@@ -149,14 +149,18 @@ namespace bx
/// Count number of bits set.
///
- BX_CONSTEXPR_FUNC uint32_t uint32_cntbits(uint32_t _val);
+ template<typename Ty>
+ BX_CONSTEXPR_FUNC uint32_t uint32_cntbits(Ty _val);
/// Count number of leading zeros.
///
- BX_CONSTEXPR_FUNC uint32_t uint32_cntlz(uint32_t _val);
+ template<typename Ty>
+ BX_CONSTEXPR_FUNC uint32_t uint32_cntlz(Ty _val);
+ /// Count number of trailing zeros.
///
- BX_CONSTEXPR_FUNC uint32_t uint32_cnttz(uint32_t _val);
+ template<typename Ty>
+ BX_CONSTEXPR_FUNC uint32_t uint32_cnttz(Ty _val);
///
BX_CONSTEXPR_FUNC uint32_t uint32_part1by1(uint32_t _a);
@@ -170,16 +174,41 @@ namespace bx
///
BX_CONSTEXPR_FUNC uint32_t uint32_nextpow2(uint32_t _a);
- /// Count number of bits set.
///
- BX_CONSTEXPR_FUNC uint32_t uint64_cntbits(uint64_t _val);
+ BX_CONSTEXPR_FUNC uint64_t uint64_li(uint64_t _a);
+
+ ///
+ BX_CONSTEXPR_FUNC uint64_t uint64_dec(uint64_t _a);
+
+ ///
+ BX_CONSTEXPR_FUNC uint64_t uint64_inc(uint64_t _a);
+
+ ///
+ BX_CONSTEXPR_FUNC uint64_t uint64_not(uint64_t _a);
+
+ ///
+ BX_CONSTEXPR_FUNC uint64_t uint64_neg(uint64_t _a);
- /// Count number of leading zeros.
///
- BX_CONSTEXPR_FUNC uint32_t uint64_cntlz(uint64_t _val);
+ BX_CONSTEXPR_FUNC uint64_t uint64_ext(uint64_t _a);
///
- BX_CONSTEXPR_FUNC uint32_t uint64_cnttz(uint64_t _val);
+ BX_CONSTEXPR_FUNC uint64_t uint64_and(uint64_t _a, uint64_t _b);
+
+ ///
+ BX_CONSTEXPR_FUNC uint64_t uint64_andc(uint64_t _a, uint64_t _b);
+
+ ///
+ BX_CONSTEXPR_FUNC uint64_t uint64_xor(uint64_t _a, uint64_t _b);
+
+ ///
+ BX_CONSTEXPR_FUNC uint64_t uint64_xorl(uint64_t _a, uint64_t _b);
+
+ ///
+ BX_CONSTEXPR_FUNC uint64_t uint64_or(uint64_t _a, uint64_t _b);
+
+ ///
+ BX_CONSTEXPR_FUNC uint64_t uint64_orc(uint64_t _a, uint64_t _b);
///
BX_CONSTEXPR_FUNC uint64_t uint64_sll(uint64_t _a, int32_t _sa);
@@ -217,13 +246,46 @@ namespace bx
///
BX_CONSTEXPR_FUNC uint32_t strideAlign(uint32_t _offset, uint32_t _stride);
- /// Align to arbitrary stride and 16-bytes.
+ /// Align to arbitrary stride and Min bytes.
+ ///
+ template<uint32_t Min>
+ BX_CONSTEXPR_FUNC uint32_t strideAlign(uint32_t _offset, uint32_t _stride);
+
+ ///
+ template<typename Ty>
+ BX_CONSTEXPR_FUNC bool isAligned(Ty _a, int32_t _align);
+
+ ///
+ template<typename Ty>
+ BX_CONSTEXPR_FUNC bool isAligned(Ty* _ptr, int32_t _align);
+
+ ///
+ template<typename Ty>
+ BX_CONSTEXPR_FUNC bool isAligned(const Ty* _ptr, int32_t _align);
+
+ ///
+ template<typename Ty>
+ BX_CONSTEXPR_FUNC Ty alignDown(Ty _a, int32_t _align);
+
+ ///
+ template<typename Ty>
+ BX_CONSTEXPR_FUNC Ty* alignDown(Ty* _ptr, int32_t _align);
+
+ ///
+ template<typename Ty>
+ BX_CONSTEXPR_FUNC const Ty* alignDown(const Ty* _ptr, int32_t _align);
+
+ ///
+ template<typename Ty>
+ BX_CONSTEXPR_FUNC Ty alignUp(Ty _a, int32_t _align);
+
///
- BX_CONSTEXPR_FUNC uint32_t strideAlign16(uint32_t _offset, uint32_t _stride);
+ template<typename Ty>
+ BX_CONSTEXPR_FUNC Ty* alignUp(Ty* _ptr, int32_t _align);
- /// Align to arbitrary stride and 256-bytes.
///
- BX_CONSTEXPR_FUNC uint32_t strideAlign256(uint32_t _offset, uint32_t _stride);
+ template<typename Ty>
+ BX_CONSTEXPR_FUNC const Ty* alignUp(const Ty* _ptr, int32_t _align);
/// Convert float to half-float.
///
diff --git a/3rdparty/bx/include/bx/url.h b/3rdparty/bx/include/bx/url.h
index 9e00d8348b4..b2b45405fe3 100644
--- a/3rdparty/bx/include/bx/url.h
+++ b/3rdparty/bx/include/bx/url.h
@@ -1,6 +1,6 @@
/*
- * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ * Copyright 2010-2022 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
*/
#ifndef BX_URL_H_HEADER_GUARD
diff --git a/3rdparty/bx/include/compat/linux/sal.h b/3rdparty/bx/include/compat/linux/sal.h
new file mode 100644
index 00000000000..23c9fc084c0
--- /dev/null
+++ b/3rdparty/bx/include/compat/linux/sal.h
@@ -0,0 +1 @@
+#include "../mingw/salieri.h"
diff --git a/3rdparty/bx/include/compat/mingw/salieri.h b/3rdparty/bx/include/compat/mingw/salieri.h
index 06d72075c3f..5942b397f32 100644
--- a/3rdparty/bx/include/compat/mingw/salieri.h
+++ b/3rdparty/bx/include/compat/mingw/salieri.h
@@ -1598,6 +1598,22 @@
# define SALIERI_DEFINED_String_length
#endif
+#if defined(_In_count_) && defined(SALIERI_DEFINED_In_count_)
+# undef _In_count_
+#endif
+#if !defined(_In_count_)
+# define _In_count_(param)
+# define SALIERI_DEFINED_In_count_
+#endif
+
+#if defined(_In_opt_count_) && defined(SALIERI_DEFINED_In_opt_count_)
+# undef _In_opt_count_
+#endif
+#if !defined(_In_opt_count_)
+# define _In_opt_count_(param)
+# define SALIERI_DEFINED_In_opt_count_
+#endif
+
#if defined(SALIERI_VERSION)
# undef SALIERI_VERSION
#endif
diff --git a/3rdparty/bx/include/compat/msvc/dirent.h b/3rdparty/bx/include/compat/msvc/dirent.h
index a08d0fa4df3..3177d335f75 100644
--- a/3rdparty/bx/include/compat/msvc/dirent.h
+++ b/3rdparty/bx/include/compat/msvc/dirent.h
@@ -1,28 +1,10 @@
/*
- * dirent.h - dirent API for Microsoft Visual Studio
+ * Dirent interface for Microsoft Visual Studio
*
- * Copyright (C) 2006-2012 Toni Ronkko
- *
- * 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 TONI RONKKO 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.
- *
- * $Id: dirent.h,v 1.20 2014/03/19 17:52:23 tronkko Exp $
+ * Copyright (C) 1998-2019 Toni Ronkko
+ * This file is part of dirent. Dirent may be freely distributed
+ * under the MIT license. For all details and documentation, see
+ * https://github.com/tronkko/dirent
*/
#ifndef DIRENT_H
#define DIRENT_H
@@ -36,21 +18,16 @@
#endif // _MSC_VER
/*
- * Define architecture flags so we don't need to include windows.h.
- * Avoiding windows.h makes it simpler to use windows sockets in conjunction
- * with dirent.h.
+ * Include windows.h without Windows Sockets 1.1 to prevent conflicts with
+ * Windows Sockets 2.0.
*/
-#if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && defined(_M_IX86)
-# define _X86_
-#endif
-#if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && defined(_M_AMD64)
-#define _AMD64_
+#ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
#endif
+#include <windows.h>
#include <stdio.h>
#include <stdarg.h>
-#include <windef.h>
-#include <winbase.h>
#include <wchar.h>
#include <string.h>
#include <stdlib.h>
@@ -70,54 +47,109 @@
# define FILE_ATTRIBUTE_DEVICE 0x40
#endif
-/* File type and permission flags for stat() */
+/* File type and permission flags for stat(), general mask */
#if !defined(S_IFMT)
-# define S_IFMT _S_IFMT /* File type mask */
+# define S_IFMT _S_IFMT
#endif
+
+/* Directory bit */
#if !defined(S_IFDIR)
-# define S_IFDIR _S_IFDIR /* Directory */
+# define S_IFDIR _S_IFDIR
#endif
+
+/* Character device bit */
#if !defined(S_IFCHR)
-# define S_IFCHR _S_IFCHR /* Character device */
+# define S_IFCHR _S_IFCHR
#endif
+
+/* Pipe bit */
#if !defined(S_IFFIFO)
-# define S_IFFIFO _S_IFFIFO /* Pipe */
+# define S_IFFIFO _S_IFFIFO
#endif
+
+/* Regular file bit */
#if !defined(S_IFREG)
-# define S_IFREG _S_IFREG /* Regular file */
+# define S_IFREG _S_IFREG
#endif
+
+/* Read permission */
#if !defined(S_IREAD)
-# define S_IREAD _S_IREAD /* Read permission */
+# define S_IREAD _S_IREAD
#endif
+
+/* Write permission */
#if !defined(S_IWRITE)
-# define S_IWRITE _S_IWRITE /* Write permission */
+# define S_IWRITE _S_IWRITE
#endif
+
+/* Execute permission */
#if !defined(S_IEXEC)
-# define S_IEXEC _S_IEXEC /* Execute permission */
+# define S_IEXEC _S_IEXEC
#endif
+
+/* Pipe */
#if !defined(S_IFIFO)
-# define S_IFIFO _S_IFIFO /* Pipe */
+# define S_IFIFO _S_IFIFO
#endif
+
+/* Block device */
#if !defined(S_IFBLK)
-# define S_IFBLK 0 /* Block device */
+# define S_IFBLK 0
#endif
+
+/* Link */
#if !defined(S_IFLNK)
-# define S_IFLNK 0 /* Link */
+# define S_IFLNK 0
#endif
+
+/* Socket */
#if !defined(S_IFSOCK)
-# define S_IFSOCK 0 /* Socket */
+# define S_IFSOCK 0
+#endif
+
+/* Read user permission */
+#if !defined(S_IRUSR)
+# define S_IRUSR S_IREAD
+#endif
+
+/* Write user permission */
+#if !defined(S_IWUSR)
+# define S_IWUSR S_IWRITE
+#endif
+
+/* Execute user permission */
+#if !defined(S_IXUSR)
+# define S_IXUSR 0
+#endif
+
+/* Read group permission */
+#if !defined(S_IRGRP)
+# define S_IRGRP 0
+#endif
+
+/* Write group permission */
+#if !defined(S_IWGRP)
+# define S_IWGRP 0
#endif
-#if defined(_MSC_VER)
-# define S_IRUSR S_IREAD /* Read user */
-# define S_IWUSR S_IWRITE /* Write user */
-# define S_IXUSR 0 /* Execute user */
-# define S_IRGRP 0 /* Read group */
-# define S_IWGRP 0 /* Write group */
-# define S_IXGRP 0 /* Execute group */
-# define S_IROTH 0 /* Read others */
-# define S_IWOTH 0 /* Write others */
-# define S_IXOTH 0 /* Execute others */
+/* Execute group permission */
+#if !defined(S_IXGRP)
+# define S_IXGRP 0
+#endif
+
+/* Read others permission */
+#if !defined(S_IROTH)
+# define S_IROTH 0
+#endif
+
+/* Write others permission */
+#if !defined(S_IWOTH)
+# define S_IWOTH 0
+#endif
+
+/* Execute others permission */
+#if !defined(S_IXOTH)
+# define S_IXOTH 0
#endif
/* Maximum length of file name */
@@ -132,14 +164,14 @@
#endif
/* File type flags for d_type */
-#define DT_UNKNOWN 0
-#define DT_REG S_IFREG
-#define DT_DIR S_IFDIR
-#define DT_FIFO S_IFIFO
-#define DT_SOCK S_IFSOCK
-#define DT_CHR S_IFCHR
-#define DT_BLK S_IFBLK
-#define DT_LNK S_IFLNK
+#define DT_UNKNOWN 0
+#define DT_REG S_IFREG
+#define DT_DIR S_IFDIR
+#define DT_FIFO S_IFIFO
+#define DT_SOCK S_IFSOCK
+#define DT_CHR S_IFCHR
+#define DT_BLK S_IFBLK
+#define DT_LNK S_IFLNK
/* Macros for converting between st_mode and d_type */
#define IFTODT(mode) ((mode) & S_IFMT)
@@ -151,39 +183,33 @@
* only defined for compatibility. These macros should always return false
* on Windows.
*/
-#ifndef S_ISFIFO
+#if !defined(S_ISFIFO)
# define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
#endif
-
-#ifndef S_ISDIR
-# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
+#if !defined(S_ISDIR)
+# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
#endif
-
-#ifndef S_ISREG
-# define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
+#if !defined(S_ISREG)
+# define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
#endif
-
-#ifndef S_ISLNK
-# define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
+#if !defined(S_ISLNK)
+# define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
#endif
-
-#ifndef S_ISSOCK
+#if !defined(S_ISSOCK)
# define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
#endif
-
-#ifndef S_ISCHR
-# define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)
+#if !defined(S_ISCHR)
+# define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)
#endif
-
-#ifndef S_ISBLK
-# define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)
+#if !defined(S_ISBLK)
+# define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)
#endif
-/* Return the exact length of d_namlen without zero terminator */
+/* Return the exact length of the file name without zero terminator */
#define _D_EXACT_NAMLEN(p) ((p)->d_namlen)
-/* Return number of bytes needed to store d_namlen */
-#define _D_ALLOC_NAMLEN(p) (PATH_MAX)
+/* Return the maximum size of a file name */
+#define _D_ALLOC_NAMLEN(p) ((PATH_MAX)+1)
#ifdef __cplusplus
@@ -193,45 +219,63 @@ extern "C" {
/* Wide-character version */
struct _wdirent {
- long d_ino; /* Always zero */
- unsigned short d_reclen; /* Structure size */
- size_t d_namlen; /* Length of name without \0 */
- int d_type; /* File type */
- wchar_t d_name[PATH_MAX]; /* File name */
+ /* Always zero */
+ long d_ino;
+
+ /* File position within stream */
+ long d_off;
+
+ /* Structure size */
+ unsigned short d_reclen;
+
+ /* Length of name without \0 */
+ size_t d_namlen;
+
+ /* File type */
+ int d_type;
+
+ /* File name */
+ wchar_t d_name[PATH_MAX+1];
};
typedef struct _wdirent _wdirent;
struct _WDIR {
- struct _wdirent ent; /* Current directory entry */
- WIN32_FIND_DATAW data; /* Private file data */
- int cached; /* True if data is valid */
- HANDLE handle; /* Win32 search handle */
- wchar_t *patt; /* Initial directory name */
+ /* Current directory entry */
+ struct _wdirent ent;
+
+ /* Private file data */
+ WIN32_FIND_DATAW data;
+
+ /* True if data is valid */
+ int cached;
+
+ /* Win32 search handle */
+ HANDLE handle;
+
+ /* Initial directory name */
+ wchar_t *patt;
};
typedef struct _WDIR _WDIR;
-static _WDIR *_wopendir (const wchar_t *dirname);
-static struct _wdirent *_wreaddir (_WDIR *dirp);
-static int _wclosedir (_WDIR *dirp);
-static void _wrewinddir (_WDIR* dirp);
+/* Multi-byte character version */
+struct dirent {
+ /* Always zero */
+ long d_ino;
+ /* File position within stream */
+ long d_off;
-/* For compatibility with Symbian */
-#define wdirent _wdirent
-#define WDIR _WDIR
-#define wopendir _wopendir
-#define wreaddir _wreaddir
-#define wclosedir _wclosedir
-#define wrewinddir _wrewinddir
+ /* Structure size */
+ unsigned short d_reclen;
+ /* Length of name without \0 */
+ size_t d_namlen;
-/* Multi-byte character versions */
-struct dirent {
- long d_ino; /* Always zero */
- unsigned short d_reclen; /* Structure size */
- size_t d_namlen; /* Length of name without \0 */
- int d_type; /* File type */
- char d_name[PATH_MAX]; /* File name */
+ /* File type */
+ int d_type;
+
+ /* File name */
+ char d_name[PATH_MAX+1];
};
typedef struct dirent dirent;
@@ -241,10 +285,41 @@ struct DIR {
};
typedef struct DIR DIR;
+
+/* Dirent functions */
static DIR *opendir (const char *dirname);
+static _WDIR *_wopendir (const wchar_t *dirname);
+
static struct dirent *readdir (DIR *dirp);
+static struct _wdirent *_wreaddir (_WDIR *dirp);
+
+static int readdir_r(
+ DIR *dirp, struct dirent *entry, struct dirent **result);
+static int _wreaddir_r(
+ _WDIR *dirp, struct _wdirent *entry, struct _wdirent **result);
+
static int closedir (DIR *dirp);
+static int _wclosedir (_WDIR *dirp);
+
static void rewinddir (DIR* dirp);
+static void _wrewinddir (_WDIR* dirp);
+
+static int scandir (const char *dirname, struct dirent ***namelist,
+ int (*filter)(const struct dirent*),
+ int (*compare)(const struct dirent**, const struct dirent**));
+
+static int alphasort (const struct dirent **a, const struct dirent **b);
+
+static int versionsort (const struct dirent **a, const struct dirent **b);
+
+
+/* For compatibility with Symbian */
+#define wdirent _wdirent
+#define WDIR _WDIR
+#define wopendir _wopendir
+#define wreaddir _wreaddir
+#define wclosedir _wclosedir
+#define wrewinddir _wrewinddir
/* Internal utility functions */
@@ -267,6 +342,7 @@ static int dirent_wcstombs_s(
static void dirent_set_errno (int error);
+
/*
* Open directory stream DIRNAME for read and return a pointer to the
* internal working area that is used to retrieve individual directory
@@ -277,7 +353,8 @@ _wopendir(
const wchar_t *dirname)
{
_WDIR *dirp = NULL;
- int error;
+ DWORD n;
+ wchar_t *p;
/* Must have directory name */
if (dirname == NULL || dirname[0] == '\0') {
@@ -287,96 +364,120 @@ _wopendir(
/* Allocate new _WDIR structure */
dirp = (_WDIR*) malloc (sizeof (struct _WDIR));
- if (dirp != NULL) {
- DWORD n;
-
- /* Reset _WDIR structure */
- dirp->handle = INVALID_HANDLE_VALUE;
- dirp->patt = NULL;
- dirp->cached = 0;
-
- /* Compute the length of full path plus zero terminator */
- n = GetFullPathNameW (dirname, 0, NULL, NULL);
-
- /* Allocate room for absolute directory name and search pattern */
- dirp->patt = (wchar_t*) malloc (sizeof (wchar_t) * n + 16);
- if (dirp->patt) {
-
- /*
- * Convert relative directory name to an absolute one. This
- * allows rewinddir() to function correctly even when current
- * working directory is changed between opendir() and rewinddir().
- */
- n = GetFullPathNameW (dirname, n, dirp->patt, NULL);
- if (n > 0) {
- wchar_t *p;
-
- /* Append search pattern \* to the directory name */
- p = dirp->patt + n;
- if (dirp->patt < p) {
- switch (p[-1]) {
- case '\\':
- case '/':
- case ':':
- /* Directory ends in path separator, e.g. c:\temp\ */
- /*NOP*/;
- break;
-
- default:
- /* Directory name doesn't end in path separator */
- *p++ = '\\';
- }
- }
- *p++ = '*';
- *p = '\0';
+ if (!dirp) {
+ return NULL;
+ }
- /* Open directory stream and retrieve the first entry */
- if (dirent_first (dirp)) {
- /* Directory stream opened successfully */
- error = 0;
- } else {
- /* Cannot retrieve first entry */
- error = 1;
- dirent_set_errno (ENOENT);
- }
+ /* Reset _WDIR structure */
+ dirp->handle = INVALID_HANDLE_VALUE;
+ dirp->patt = NULL;
+ dirp->cached = 0;
+
+ /*
+ * Compute the length of full path plus zero terminator
+ *
+ * Note that on WinRT there's no way to convert relative paths
+ * into absolute paths, so just assume it is an absolute path.
+ */
+#if defined(WINAPI_FAMILY) && defined(WINAPI_FAMILY_PHONE_APP) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
+ /* WinRT */
+ n = wcslen (dirname);
+#else
+ /* Regular Windows */
+ n = GetFullPathNameW (dirname, 0, NULL, NULL);
+#endif
- } else {
- /* Cannot retrieve full path name */
- dirent_set_errno (ENOENT);
- error = 1;
- }
+ /* Allocate room for absolute directory name and search pattern */
+ dirp->patt = (wchar_t*) malloc (sizeof (wchar_t) * n + 16);
+ if (dirp->patt == NULL) {
+ goto exit_closedir;
+ }
- } else {
- /* Cannot allocate memory for search pattern */
- error = 1;
- }
+ /*
+ * Convert relative directory name to an absolute one. This
+ * allows rewinddir() to function correctly even when current
+ * working directory is changed between opendir() and rewinddir().
+ *
+ * Note that on WinRT there's no way to convert relative paths
+ * into absolute paths, so just assume it is an absolute path.
+ */
+#if defined(WINAPI_FAMILY) && defined(WINAPI_FAMILY_PHONE_APP) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
+ /* WinRT */
+ wcsncpy_s (dirp->patt, n+1, dirname, n);
+#else
+ /* Regular Windows */
+ n = GetFullPathNameW (dirname, n, dirp->patt, NULL);
+ if (n <= 0) {
+ goto exit_closedir;
+ }
+#endif
- } else {
- /* Cannot allocate _WDIR structure */
- error = 1;
+ /* Append search pattern \* to the directory name */
+ p = dirp->patt + n;
+ switch (p[-1]) {
+ case '\\':
+ case '/':
+ case ':':
+ /* Directory ends in path separator, e.g. c:\temp\ */
+ /*NOP*/;
+ break;
+
+ default:
+ /* Directory name doesn't end in path separator */
+ *p++ = '\\';
}
+ *p++ = '*';
+ *p = '\0';
- /* Clean up in case of error */
- if (error && dirp) {
- _wclosedir (dirp);
- dirp = NULL;
+ /* Open directory stream and retrieve the first entry */
+ if (!dirent_first (dirp)) {
+ goto exit_closedir;
}
+ /* Success */
return dirp;
+
+ /* Failure */
+exit_closedir:
+ _wclosedir (dirp);
+ return NULL;
}
/*
- * Read next directory entry. The directory entry is returned in dirent
- * structure in the d_name field. Individual directory entries returned by
- * this function include regular files, sub-directories, pseudo-directories
- * "." and ".." as well as volume labels, hidden files and system files.
+ * Read next directory entry.
+ *
+ * Returns pointer to static directory entry which may be overwritten by
+ * subsequent calls to _wreaddir().
*/
static struct _wdirent*
_wreaddir(
_WDIR *dirp)
{
+ struct _wdirent *entry;
+
+ /*
+ * Read directory entry to buffer. We can safely ignore the return value
+ * as entry will be set to NULL in case of error.
+ */
+ (void) _wreaddir_r (dirp, &dirp->ent, &entry);
+
+ /* Return pointer to statically allocated directory entry */
+ return entry;
+}
+
+/*
+ * Read next directory entry.
+ *
+ * Returns zero on success. If end of directory stream is reached, then sets
+ * result to NULL and returns zero.
+ */
+static int
+_wreaddir_r(
+ _WDIR *dirp,
+ struct _wdirent *entry,
+ struct _wdirent **result)
+{
WIN32_FIND_DATAW *datap;
- struct _wdirent *entp;
/* Read next directory entry */
datap = dirent_next (dirp);
@@ -384,46 +485,47 @@ _wreaddir(
size_t n;
DWORD attr;
- /* Pointer to directory entry to return */
- entp = &dirp->ent;
-
/*
* Copy file name as wide-character string. If the file name is too
* long to fit in to the destination buffer, then truncate file name
* to PATH_MAX characters and zero-terminate the buffer.
*/
n = 0;
- while (n + 1 < PATH_MAX && datap->cFileName[n] != 0) {
- entp->d_name[n] = datap->cFileName[n];
+ while (n < PATH_MAX && datap->cFileName[n] != 0) {
+ entry->d_name[n] = datap->cFileName[n];
n++;
}
- dirp->ent.d_name[n] = 0;
+ entry->d_name[n] = 0;
/* Length of file name excluding zero terminator */
- entp->d_namlen = n;
+ entry->d_namlen = n;
/* File type */
attr = datap->dwFileAttributes;
if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
- entp->d_type = DT_CHR;
+ entry->d_type = DT_CHR;
} else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
- entp->d_type = DT_DIR;
+ entry->d_type = DT_DIR;
} else {
- entp->d_type = DT_REG;
+ entry->d_type = DT_REG;
}
/* Reset dummy fields */
- entp->d_ino = 0;
- entp->d_reclen = sizeof (struct _wdirent);
+ entry->d_ino = 0;
+ entry->d_off = 0;
+ entry->d_reclen = sizeof (struct _wdirent);
+
+ /* Set result address */
+ *result = entry;
} else {
- /* Last directory entry read */
- entp = NULL;
+ /* Return NULL to indicate end of directory */
+ *result = NULL;
}
- return entp;
+ return /*OK*/0;
}
/*
@@ -441,23 +543,21 @@ _wclosedir(
/* Release search handle */
if (dirp->handle != INVALID_HANDLE_VALUE) {
FindClose (dirp->handle);
- dirp->handle = INVALID_HANDLE_VALUE;
}
/* Release search pattern */
- if (dirp->patt) {
- free (dirp->patt);
- dirp->patt = NULL;
- }
+ free (dirp->patt);
/* Release directory structure */
free (dirp);
ok = /*success*/0;
} else {
+
/* Invalid directory stream */
dirent_set_errno (EBADF);
ok = /*failure*/-1;
+
}
return ok;
}
@@ -487,9 +587,12 @@ dirent_first(
_WDIR *dirp)
{
WIN32_FIND_DATAW *datap;
+ DWORD error;
/* Open directory and retrieve the first entry */
- dirp->handle = FindFirstFileW (dirp->patt, &dirp->data);
+ dirp->handle = FindFirstFileExW(
+ dirp->patt, FindExInfoStandard, &dirp->data,
+ FindExSearchNameMatch, NULL, 0);
if (dirp->handle != INVALID_HANDLE_VALUE) {
/* a directory entry is now waiting in memory */
@@ -498,15 +601,38 @@ dirent_first(
} else {
- /* Failed to re-open directory: no directory entry in memory */
+ /* Failed to open directory: no directory entry in memory */
dirp->cached = 0;
datap = NULL;
+ /* Set error code */
+ error = GetLastError ();
+ switch (error) {
+ case ERROR_ACCESS_DENIED:
+ /* No read access to directory */
+ dirent_set_errno (EACCES);
+ break;
+
+ case ERROR_DIRECTORY:
+ /* Directory name is invalid */
+ dirent_set_errno (ENOTDIR);
+ break;
+
+ case ERROR_PATH_NOT_FOUND:
+ default:
+ /* Cannot find the file */
+ dirent_set_errno (ENOENT);
+ }
+
}
return datap;
}
-/* Get next directory entry (internal) */
+/*
+ * Get next directory entry (internal).
+ *
+ * Returns
+ */
static WIN32_FIND_DATAW*
dirent_next(
_WDIR *dirp)
@@ -527,7 +653,7 @@ dirent_next(
/* Got a file */
p = &dirp->data;
} else {
- /* The very last entry has been processed or an error occured */
+ /* The very last entry has been processed or an error occurred */
FindClose (dirp->handle);
dirp->handle = INVALID_HANDLE_VALUE;
p = NULL;
@@ -552,6 +678,8 @@ opendir(
{
struct DIR *dirp;
int error;
+ wchar_t wname[PATH_MAX + 1];
+ size_t n;
/* Must have directory name */
if (dirname == NULL || dirname[0] == '\0') {
@@ -561,67 +689,71 @@ opendir(
/* Allocate memory for DIR structure */
dirp = (DIR*) malloc (sizeof (struct DIR));
- if (dirp) {
- wchar_t wname[PATH_MAX];
- size_t n;
-
- /* Convert directory name to wide-character string */
- error = dirent_mbstowcs_s (&n, wname, PATH_MAX, dirname, PATH_MAX);
- if (!error) {
-
- /* Open directory stream using wide-character name */
- dirp->wdirp = _wopendir (wname);
- if (dirp->wdirp) {
- /* Directory stream opened */
- error = 0;
- } else {
- /* Failed to open directory stream */
- error = 1;
- }
-
- } else {
- /*
- * Cannot convert file name to wide-character string. This
- * occurs if the string contains invalid multi-byte sequences or
- * the output buffer is too small to contain the resulting
- * string.
- */
- error = 1;
- }
+ if (!dirp) {
+ return NULL;
+ }
- } else {
- /* Cannot allocate DIR structure */
- error = 1;
+ /* Convert directory name to wide-character string */
+ error = dirent_mbstowcs_s(
+ &n, wname, PATH_MAX + 1, dirname, PATH_MAX + 1);
+ if (error) {
+ /*
+ * Cannot convert file name to wide-character string. This
+ * occurs if the string contains invalid multi-byte sequences or
+ * the output buffer is too small to contain the resulting
+ * string.
+ */
+ goto exit_free;
}
- /* Clean up in case of error */
- if (error && dirp) {
- free (dirp);
- dirp = NULL;
+
+ /* Open directory stream using wide-character name */
+ dirp->wdirp = _wopendir (wname);
+ if (!dirp->wdirp) {
+ goto exit_free;
}
+ /* Success */
return dirp;
+
+ /* Failure */
+exit_free:
+ free (dirp);
+ return NULL;
}
/*
* Read next directory entry.
- *
- * When working with text consoles, please note that file names returned by
- * readdir() are represented in the default ANSI code page while any output to
- * console is typically formatted on another code page. Thus, non-ASCII
- * characters in file names will not usually display correctly on console. The
- * problem can be fixed in two ways: (1) change the character set of console
- * to 1252 using chcp utility and use Lucida Console font, or (2) use
- * _cprintf function when writing to console. The _cprinf() will re-encode
- * ANSI strings to the console code page so many non-ASCII characters will
- * display correcly.
*/
static struct dirent*
readdir(
DIR *dirp)
{
+ struct dirent *entry;
+
+ /*
+ * Read directory entry to buffer. We can safely ignore the return value
+ * as entry will be set to NULL in case of error.
+ */
+ (void) readdir_r (dirp, &dirp->ent, &entry);
+
+ /* Return pointer to statically allocated directory entry */
+ return entry;
+}
+
+/*
+ * Read next directory entry into called-allocated buffer.
+ *
+ * Returns zero on success. If the end of directory stream is reached, then
+ * sets result to NULL and returns zero.
+ */
+static int
+readdir_r(
+ DIR *dirp,
+ struct dirent *entry,
+ struct dirent **result)
+{
WIN32_FIND_DATAW *datap;
- struct dirent *entp;
/* Read next directory entry */
datap = dirent_next (dirp->wdirp);
@@ -631,7 +763,7 @@ readdir(
/* Attempt to convert file name to multi-byte string */
error = dirent_wcstombs_s(
- &n, dirp->ent.d_name, PATH_MAX, datap->cFileName, PATH_MAX);
+ &n, entry->d_name, PATH_MAX + 1, datap->cFileName, PATH_MAX + 1);
/*
* If the file name cannot be represented by a multi-byte string,
@@ -645,55 +777,60 @@ readdir(
*/
if (error && datap->cAlternateFileName[0] != '\0') {
error = dirent_wcstombs_s(
- &n, dirp->ent.d_name, PATH_MAX,
- datap->cAlternateFileName, PATH_MAX);
+ &n, entry->d_name, PATH_MAX + 1,
+ datap->cAlternateFileName, PATH_MAX + 1);
}
if (!error) {
DWORD attr;
- /* Initialize directory entry for return */
- entp = &dirp->ent;
-
/* Length of file name excluding zero terminator */
- entp->d_namlen = n - 1;
+ entry->d_namlen = n - 1;
/* File attributes */
attr = datap->dwFileAttributes;
if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
- entp->d_type = DT_CHR;
+ entry->d_type = DT_CHR;
} else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
- entp->d_type = DT_DIR;
+ entry->d_type = DT_DIR;
} else {
- entp->d_type = DT_REG;
+ entry->d_type = DT_REG;
}
/* Reset dummy fields */
- entp->d_ino = 0;
- entp->d_reclen = sizeof (struct dirent);
+ entry->d_ino = 0;
+ entry->d_off = 0;
+ entry->d_reclen = sizeof (struct dirent);
} else {
+
/*
* Cannot convert file name to multi-byte string so construct
- * an errornous directory entry and return that. Note that
+ * an erroneous directory entry and return that. Note that
* we cannot return NULL as that would stop the processing
* of directory entries completely.
*/
- entp = &dirp->ent;
- entp->d_name[0] = '?';
- entp->d_name[1] = '\0';
- entp->d_namlen = 1;
- entp->d_type = DT_UNKNOWN;
- entp->d_ino = 0;
- entp->d_reclen = 0;
+ entry->d_name[0] = '?';
+ entry->d_name[1] = '\0';
+ entry->d_namlen = 1;
+ entry->d_type = DT_UNKNOWN;
+ entry->d_ino = 0;
+ entry->d_off = -1;
+ entry->d_reclen = 0;
+
}
+ /* Return pointer to directory entry */
+ *result = entry;
+
} else {
+
/* No more directory entries */
- entp = NULL;
+ *result = NULL;
+
}
- return entp;
+ return /*OK*/0;
}
/*
@@ -734,6 +871,162 @@ rewinddir(
_wrewinddir (dirp->wdirp);
}
+/*
+ * Scan directory for entries.
+ */
+static int
+scandir(
+ const char *dirname,
+ struct dirent ***namelist,
+ int (*filter)(const struct dirent*),
+ int (*compare)(const struct dirent**, const struct dirent**))
+{
+ struct dirent **files = NULL;
+ size_t size = 0;
+ size_t allocated = 0;
+ const size_t init_size = 1;
+ DIR *dir = NULL;
+ struct dirent *entry;
+ struct dirent *tmp = NULL;
+ size_t i;
+ int result = 0;
+
+ /* Open directory stream */
+ dir = opendir (dirname);
+ if (dir) {
+
+ /* Read directory entries to memory */
+ while (1) {
+
+ /* Enlarge pointer table to make room for another pointer */
+ if (size >= allocated) {
+ void *p;
+ size_t num_entries;
+
+ /* Compute number of entries in the enlarged pointer table */
+ if (size < init_size) {
+ /* Allocate initial pointer table */
+ num_entries = init_size;
+ } else {
+ /* Double the size */
+ num_entries = size * 2;
+ }
+
+ /* Allocate first pointer table or enlarge existing table */
+ p = realloc (files, sizeof (void*) * num_entries);
+ if (p != NULL) {
+ /* Got the memory */
+ files = (dirent**) p;
+ allocated = num_entries;
+ } else {
+ /* Out of memory */
+ result = -1;
+ break;
+ }
+
+ }
+
+ /* Allocate room for temporary directory entry */
+ if (tmp == NULL) {
+ tmp = (struct dirent*) malloc (sizeof (struct dirent));
+ if (tmp == NULL) {
+ /* Cannot allocate temporary directory entry */
+ result = -1;
+ break;
+ }
+ }
+
+ /* Read directory entry to temporary area */
+ if (readdir_r (dir, tmp, &entry) == /*OK*/0) {
+
+ /* Did we get an entry? */
+ if (entry != NULL) {
+ int pass;
+
+ /* Determine whether to include the entry in result */
+ if (filter) {
+ /* Let the filter function decide */
+ pass = filter (tmp);
+ } else {
+ /* No filter function, include everything */
+ pass = 1;
+ }
+
+ if (pass) {
+ /* Store the temporary entry to pointer table */
+ files[size++] = tmp;
+ tmp = NULL;
+
+ /* Keep up with the number of files */
+ result++;
+ }
+
+ } else {
+
+ /*
+ * End of directory stream reached => sort entries and
+ * exit.
+ */
+ qsort (files, size, sizeof (void*),
+ (int (*) (const void*, const void*)) compare);
+ break;
+
+ }
+
+ } else {
+ /* Error reading directory entry */
+ result = /*Error*/ -1;
+ break;
+ }
+
+ }
+
+ } else {
+ /* Cannot open directory */
+ result = /*Error*/ -1;
+ }
+
+ /* Release temporary directory entry */
+ free (tmp);
+
+ /* Release allocated memory on error */
+ if (result < 0) {
+ for (i = 0; i < size; i++) {
+ free (files[i]);
+ }
+ free (files);
+ files = NULL;
+ }
+
+ /* Close directory stream */
+ if (dir) {
+ closedir (dir);
+ }
+
+ /* Pass pointer table to caller */
+ if (namelist) {
+ *namelist = files;
+ }
+ return result;
+}
+
+/* Alphabetical sorting */
+static int
+alphasort(
+ const struct dirent **a, const struct dirent **b)
+{
+ return strcoll ((*a)->d_name, (*b)->d_name);
+}
+
+/* Sort versions */
+static int
+versionsort(
+ const struct dirent **a, const struct dirent **b)
+{
+ /* FIXME: implement strverscmp and use that */
+ return alphasort (a, b);
+}
+
/* Convert multi-byte string to wide character string */
static int
dirent_mbstowcs_s(
@@ -744,46 +1037,87 @@ dirent_mbstowcs_s(
size_t count)
{
int error;
-
-#if defined(_MSC_VER) && _MSC_VER >= 1400
-
- /* Microsoft Visual Studio 2005 or later */
- error = mbstowcs_s (pReturnValue, wcstr, sizeInWords, mbstr, count);
-
+ int n;
+ size_t len;
+ UINT cp;
+ DWORD flags;
+
+ /* Determine code page for multi-byte string */
+#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
+ if (AreFileApisANSI ()) {
+ /* Default ANSI code page */
+ cp = GetACP ();
+ } else {
+ /* Default OEM code page */
+ cp = GetOEMCP ();
+ }
#else
+ cp = CP_ACP;
+#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
+
+ /*
+ * Determine flags based on the character set. For more information,
+ * please see https://docs.microsoft.com/fi-fi/windows/desktop/api/stringapiset/nf-stringapiset-multibytetowidechar
+ */
+ switch (cp) {
+ case 42:
+ case 50220:
+ case 50221:
+ case 50222:
+ case 50225:
+ case 50227:
+ case 50229:
+ case 57002:
+ case 57003:
+ case 57004:
+ case 57005:
+ case 57006:
+ case 57007:
+ case 57008:
+ case 57009:
+ case 57010:
+ case 57011:
+ case 65000:
+ /* MultiByteToWideChar does not support MB_ERR_INVALID_CHARS */
+ flags = 0;
+ break;
+
+ default:
+ /*
+ * Ask MultiByteToWideChar to return an error if a multi-byte
+ * character cannot be converted to a wide-character.
+ */
+ flags = MB_ERR_INVALID_CHARS;
+ }
- /* Older Visual Studio or non-Microsoft compiler */
- size_t n;
+ /* Compute the length of input string without zero-terminator */
+ len = 0;
+ while (mbstr[len] != '\0' && len < count) {
+ len++;
+ }
- /* Convert to wide-character string (or count characters) */
- n = mbstowcs (wcstr, mbstr, sizeInWords);
- if (!wcstr || n < count) {
+ /* Convert to wide-character string */
+ n = MultiByteToWideChar(
+ /* Source code page */ cp,
+ /* Flags */ flags,
+ /* Pointer to string to convert */ mbstr,
+ /* Size of multi-byte string */ (int) len,
+ /* Pointer to output buffer */ wcstr,
+ /* Size of output buffer */ (int)sizeInWords - 1
+ );
- /* Zero-terminate output buffer */
- if (wcstr && sizeInWords) {
- if (n >= sizeInWords) {
- n = sizeInWords - 1;
- }
- wcstr[n] = 0;
- }
+ /* Ensure that output buffer is zero-terminated */
+ wcstr[n] = '\0';
- /* Length of resuting multi-byte string WITH zero terminator */
- if (pReturnValue) {
- *pReturnValue = n + 1;
- }
+ /* Return length of wide-character string with zero-terminator */
+ *pReturnValue = (size_t) (n + 1);
- /* Success */
+ /* Return zero if conversion succeeded */
+ if (n > 0) {
error = 0;
-
} else {
-
- /* Could not convert string */
error = 1;
-
}
-
-#endif
-
return error;
}
@@ -796,47 +1130,82 @@ dirent_wcstombs_s(
const wchar_t *wcstr,
size_t count)
{
+ int n;
int error;
-
-#if defined(_MSC_VER) && _MSC_VER >= 1400
-
- /* Microsoft Visual Studio 2005 or later */
- error = wcstombs_s (pReturnValue, mbstr, sizeInBytes, wcstr, count);
-
+ UINT cp;
+ size_t len;
+ BOOL flag = 0;
+ LPBOOL pflag;
+
+ /* Determine code page for multi-byte string */
+#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
+ if (AreFileApisANSI ()) {
+ /* Default ANSI code page */
+ cp = GetACP ();
+ } else {
+ /* Default OEM code page */
+ cp = GetOEMCP ();
+ }
#else
+ cp = CP_ACP;
+#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
- /* Older Visual Studio or non-Microsoft compiler */
- size_t n;
- /* Convert to multi-byte string (or count the number of bytes needed) */
- n = wcstombs (mbstr, wcstr, sizeInBytes);
- if (!mbstr || n < count) {
+ /* Compute the length of input string without zero-terminator */
+ len = 0;
+ while (wcstr[len] != '\0' && len < count) {
+ len++;
+ }
- /* Zero-terminate output buffer */
- if (mbstr && sizeInBytes) {
- if (n >= sizeInBytes) {
- n = sizeInBytes - 1;
- }
- mbstr[n] = '\0';
- }
+ /*
+ * Determine if we can ask WideCharToMultiByte to return information on
+ * broken characters. For more information, please see
+ * https://docs.microsoft.com/en-us/windows/desktop/api/stringapiset/nf-stringapiset-widechartomultibyte
+ */
+ switch (cp) {
+ case CP_UTF7:
+ case CP_UTF8:
+ /*
+ * WideCharToMultiByte fails if we request information on default
+ * characters. This is just a nuisance but doesn't affect the
+ * conversion: if Windows is configured to use UTF-8, then the default
+ * character should not be needed anyway.
+ */
+ pflag = NULL;
+ break;
- /* Lenght of resulting multi-bytes string WITH zero-terminator */
- if (pReturnValue) {
- *pReturnValue = n + 1;
- }
+ default:
+ /*
+ * Request that WideCharToMultiByte sets the flag if it uses the
+ * default character.
+ */
+ pflag = &flag;
+ }
- /* Success */
+ /* Convert wide-character string to multi-byte character string */
+ n = WideCharToMultiByte(
+ /* Target code page */ cp,
+ /* Flags */ 0,
+ /* Pointer to unicode string */ wcstr,
+ /* Length of unicode string */ (int) len,
+ /* Pointer to output buffer */ mbstr,
+ /* Size of output buffer */ (int)sizeInBytes - 1,
+ /* Default character */ NULL,
+ /* Whether default character was used or not */ pflag
+ );
+
+ /* Ensure that output buffer is zero-terminated */
+ mbstr[n] = '\0';
+
+ /* Return length of multi-byte string with zero-terminator */
+ *pReturnValue = (size_t) (n + 1);
+
+ /* Return zero if conversion succeeded without using default characters */
+ if (n > 0 && flag == 0) {
error = 0;
-
} else {
-
- /* Cannot convert string */
error = 1;
-
}
-
-#endif
-
return error;
}
@@ -858,6 +1227,7 @@ dirent_set_errno(
#endif
}
+
#ifdef __cplusplus
}
#endif