diff options
Diffstat (limited to '3rdparty/bx/include')
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 |