diff --git a/CMakeLists.txt b/CMakeLists.txt index 34f2166..5c6e2cb 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,9 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake) set(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} "${PROJECT_SOURCE_DIR}/deps/include") -if(MINGW) + set(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} "${PROJECT_SOURCE_DIR}/deps/lib/linux-gcc/x64") +if(UNIX AND CMAKE_COMPILER_IS_GNUCXX) +elseif(MINGW) set(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} "${PROJECT_SOURCE_DIR}/deps/lib/mingw/x64") elseif(MSVC) set(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} "${PROJECT_SOURCE_DIR}/deps/lib/msvc12/x64") @@ -13,8 +15,11 @@ endif() if(CMAKE_COMPILER_IS_GNUCXX) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -fpermissive") + # Needed to link with debug version of bgfx + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -ldl") endif() +set(BUILD_SHARED_LIBS OFF) include_directories(${PROJECT_SOURCE_DIR}/include) #set(GLEW_INCLUDE_DIR ${daydream_SOURCE_DIR}/libs/glew-1.11.0/include) diff --git a/deps/include/bx/allocator.h b/deps/include/bx/allocator.h new file mode 100644 index 0000000..8d3e88c --- /dev/null +++ b/deps/include/bx/allocator.h @@ -0,0 +1,208 @@ +/* + * Copyright 2010-2015 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#ifndef BX_ALLOCATOR_H_HEADER_GUARD +#define BX_ALLOCATOR_H_HEADER_GUARD + +#include "bx.h" + +#include +#include //::memmove +#include + +#if BX_CONFIG_ALLOCATOR_CRT +# include +#endif // BX_CONFIG_ALLOCATOR_CRT + +#if BX_CONFIG_ALLOCATOR_DEBUG +# define BX_ALLOC(_allocator, _size) bx::alloc(_allocator, _size, 0, __FILE__, __LINE__) +# define BX_REALLOC(_allocator, _ptr, _size) bx::realloc(_allocator, _ptr, _size, 0, __FILE__, __LINE__) +# define BX_FREE(_allocator, _ptr) bx::free(_allocator, _ptr, 0, __FILE__, __LINE__) +# define BX_ALIGNED_ALLOC(_allocator, _size, _align) bx::alloc(_allocator, _size, _align, __FILE__, __LINE__) +# define BX_ALIGNED_REALLOC(_allocator, _ptr, _size, _align) bx::realloc(_allocator, _ptr, _size, _align, __FILE__, __LINE__) +# define BX_ALIGNED_FREE(_allocator, _ptr, _align) bx::free(_allocator, _ptr, _align, __FILE__, __LINE__) +# define BX_NEW(_allocator, _type) ::new(BX_ALLOC(_allocator, sizeof(_type) ) ) _type +# define BX_DELETE(_allocator, _ptr) bx::deleteObject(_allocator, _ptr, 0, __FILE__, __LINE__) +# define BX_ALIGNED_NEW(_allocator, _type, _align) ::new(BX_ALIGNED_ALLOC(_allocator, sizeof(_type), _align) ) _type +# define BX_ALIGNED_DELETE(_allocator, _ptr, _align) bx::deleteObject(_allocator, _ptr, _align, __FILE__, __LINE__) +#else +# define BX_ALLOC(_allocator, _size) bx::alloc(_allocator, _size, 0) +# define BX_REALLOC(_allocator, _ptr, _size) bx::realloc(_allocator, _ptr, _size, 0) +# define BX_FREE(_allocator, _ptr) bx::free(_allocator, _ptr, 0) +# define BX_ALIGNED_ALLOC(_allocator, _size, _align) bx::alloc(_allocator, _size, _align) +# define BX_ALIGNED_REALLOC(_allocator, _ptr, _size, _align) bx::realloc(_allocator, _ptr, _size, _align) +# define BX_ALIGNED_FREE(_allocator, _ptr, _align) bx::free(_allocator, _ptr, _align) +# define BX_NEW(_allocator, _type) ::new(BX_ALLOC(_allocator, sizeof(_type) ) ) _type +# define BX_DELETE(_allocator, _ptr) bx::deleteObject(_allocator, _ptr, 0) +# define BX_ALIGNED_NEW(_allocator, _type, _align) ::new(BX_ALIGNED_ALLOC(_allocator, sizeof(_type), _align) ) _type +# define BX_ALIGNED_DELETE(_allocator, _ptr, _align) bx::deleteObject(_allocator, _ptr, _align) +#endif // BX_CONFIG_DEBUG_ALLOC + +#ifndef BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT +# define BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT 8 +#endif // BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT + +namespace bx +{ + /// Aligns pointer to nearest next aligned address. _align must be power of two. + inline void* alignPtr(void* _ptr, size_t _extra, size_t _align = BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT) + { + union { void* ptr; size_t addr; } un; + un.ptr = _ptr; + size_t unaligned = un.addr + _extra; // space for header + size_t mask = _align-1; + size_t aligned = BX_ALIGN_MASK(unaligned, mask); + un.addr = aligned; + return un.ptr; + } + + struct BX_NO_VTABLE AllocatorI + { + virtual ~AllocatorI() = 0; + virtual void* alloc(size_t _size, size_t _align, const char* _file, uint32_t _line) = 0; + virtual void free(void* _ptr, size_t _align, const char* _file, uint32_t _line) = 0; + }; + + inline AllocatorI::~AllocatorI() + { + } + + struct BX_NO_VTABLE ReallocatorI : public AllocatorI + { + virtual void* realloc(void* _ptr, size_t _size, size_t _align, const char* _file, uint32_t _line) = 0; + }; + + inline void* alloc(AllocatorI* _allocator, size_t _size, size_t _align = 0, const char* _file = NULL, uint32_t _line = 0) + { + return _allocator->alloc(_size, _align, _file, _line); + } + + inline void free(AllocatorI* _allocator, void* _ptr, size_t _align = 0, const char* _file = NULL, uint32_t _line = 0) + { + _allocator->free(_ptr, _align, _file, _line); + } + + inline void* realloc(ReallocatorI* _allocator, void* _ptr, size_t _size, size_t _align = 0, const char* _file = NULL, uint32_t _line = 0) + { + return _allocator->realloc(_ptr, _size, _align, _file, _line); + } + + static inline void* alignedAlloc(AllocatorI* _allocator, size_t _size, size_t _align, const char* _file = NULL, uint32_t _line = 0) + { + size_t total = _size + _align; + uint8_t* ptr = (uint8_t*)alloc(_allocator, total, 0, _file, _line); + uint8_t* aligned = (uint8_t*)alignPtr(ptr, sizeof(uint32_t), _align); + uint32_t* header = (uint32_t*)aligned - 1; + *header = uint32_t(aligned - ptr); + return aligned; + } + + static inline void alignedFree(AllocatorI* _allocator, void* _ptr, size_t /*_align*/, const char* _file = NULL, uint32_t _line = 0) + { + uint8_t* aligned = (uint8_t*)_ptr; + uint32_t* header = (uint32_t*)aligned - 1; + uint8_t* ptr = aligned - *header; + free(_allocator, ptr, 0, _file, _line); + } + + static inline void* alignedRealloc(ReallocatorI* _allocator, void* _ptr, size_t _size, size_t _align, const char* _file = NULL, uint32_t _line = 0) + { + if (NULL == _ptr) + { + return alignedAlloc(_allocator, _size, _align, _file, _line); + } + + uint8_t* aligned = (uint8_t*)_ptr; + uint32_t offset = *( (uint32_t*)aligned - 1); + uint8_t* ptr = aligned - offset; + size_t total = _size + _align; + ptr = (uint8_t*)realloc(_allocator, ptr, total, 0, _file, _line); + uint8_t* newAligned = (uint8_t*)alignPtr(ptr, sizeof(uint32_t), _align); + + if (newAligned == aligned) + { + return aligned; + } + + aligned = ptr + offset; + ::memmove(newAligned, aligned, _size); + uint32_t* header = (uint32_t*)newAligned - 1; + *header = uint32_t(newAligned - ptr); + return newAligned; + } + + template + inline void deleteObject(AllocatorI* _allocator, ObjectT* _object, size_t _align = 0, const char* _file = NULL, uint32_t _line = 0) + { + if (NULL != _object) + { + _object->~ObjectT(); + free(_allocator, _object, _align, _file, _line); + } + } + +#if BX_CONFIG_ALLOCATOR_CRT + class CrtAllocator : public ReallocatorI + { + public: + CrtAllocator() + { + } + + virtual ~CrtAllocator() + { + } + + virtual void* alloc(size_t _size, size_t _align, const char* _file, uint32_t _line) BX_OVERRIDE + { + if (BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT >= _align) + { + return ::malloc(_size); + } + +# if BX_COMPILER_MSVC + BX_UNUSED(_file, _line); + return _aligned_malloc(_size, _align); +# else + return bx::alignedAlloc(this, _size, _align, _file, _line); +# endif // BX_ + } + + virtual void free(void* _ptr, size_t _align, const char* _file, uint32_t _line) BX_OVERRIDE + { + if (BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT >= _align) + { + ::free(_ptr); + return; + } + +# if BX_COMPILER_MSVC + BX_UNUSED(_file, _line); + _aligned_free(_ptr); +# else + bx::alignedFree(this, _ptr, _align, _file, _line); +# endif // BX_ + } + + virtual void* realloc(void* _ptr, size_t _size, size_t _align, const char* _file, uint32_t _line) BX_OVERRIDE + { + if (BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT >= _align) + { + return ::realloc(_ptr, _size); + } + +# if BX_COMPILER_MSVC + BX_UNUSED(_file, _line); + return _aligned_realloc(_ptr, _size, _align); +# else + return bx::alignedRealloc(this, _ptr, _size, _align, _file, _line); +# endif // BX_ + } + }; +#endif // BX_CONFIG_ALLOCATOR_CRT + +} // namespace bx + +#endif // BX_ALLOCATOR_H_HEADER_GUARD diff --git a/deps/include/bx/blockalloc.h b/deps/include/bx/blockalloc.h new file mode 100644 index 0000000..5bbeb1f --- /dev/null +++ b/deps/include/bx/blockalloc.h @@ -0,0 +1,99 @@ +/* + * Copyright 2010-2015 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#ifndef BX_BLOCKALLOC_H_HEADER_GUARD +#define BX_BLOCKALLOC_H_HEADER_GUARD + +#include "bx.h" + +namespace bx +{ + class BlockAlloc + { + public: + static const uint16_t invalidIndex = 0xffff; + static const uint32_t minElementSize = 2; + + BlockAlloc() + : m_data(NULL) + , m_num(0) + , m_size(0) + , m_numFree(0) + , m_freeIndex(invalidIndex) + { + } + + BlockAlloc(void* _data, uint16_t _num, uint16_t _size) + : m_data(_data) + , m_num(_num) + , m_size(_size) + , m_numFree(_num) + , m_freeIndex(0) + { + char* data = (char*)_data; + uint16_t* index = (uint16_t*)_data; + for (uint16_t ii = 0; ii < m_num-1; ++ii) + { + *index = ii+1; + data += m_size; + index = (uint16_t*)data; + } + *index = invalidIndex; + } + + ~BlockAlloc() + { + } + + void* alloc() + { + if (invalidIndex == m_freeIndex) + { + return NULL; + } + + void* obj = ( (char*)m_data) + m_freeIndex*m_size; + m_freeIndex = *( (uint16_t*)obj); + --m_numFree; + + return obj; + } + + void free(void* _obj) + { + uint16_t index = getIndex(_obj); + BX_CHECK(index < m_num, "index %d, m_num %d", index, m_num); + + *( (uint16_t*)_obj) = m_freeIndex; + m_freeIndex = index; + ++m_numFree; + } + + uint16_t getIndex(void* _obj) const + { + return (uint16_t)( ( (char*)_obj - (char*)m_data ) / m_size); + } + + uint16_t getNumFree() const + { + return m_numFree; + } + + void* getFromIndex(uint16_t _index) + { + return (char*)m_data + _index*m_size; + } + + private: + void* m_data; + uint16_t m_num; + uint16_t m_size; + uint16_t m_numFree; + uint16_t m_freeIndex; + }; + +} // namespace bx + +#endif // BX_BLOCKALLOC_H_HEADER_GUARD diff --git a/deps/include/bx/bx.h b/deps/include/bx/bx.h new file mode 100644 index 0000000..48ba970 --- /dev/null +++ b/deps/include/bx/bx.h @@ -0,0 +1,60 @@ +/* + * Copyright 2010-2015 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#ifndef BX_H_HEADER_GUARD +#define BX_H_HEADER_GUARD + +#include // uint32_t +#include // size_t + +#include "config.h" +#include "macros.h" + +namespace bx +{ + // http://cnicholson.net/2011/01/stupid-c-tricks-a-better-sizeof_array/ + template char (&COUNTOF_REQUIRES_ARRAY_ARGUMENT(const T(&)[N]) )[N]; +#define BX_COUNTOF(_x) sizeof(bx::COUNTOF_REQUIRES_ARRAY_ARGUMENT(_x) ) + + // Template for avoiding MSVC: C4127: conditional expression is constant + template + inline bool isEnabled() + { + return true; + } + + template<> + inline bool isEnabled() + { + return false; + } +#define BX_ENABLED(_x) bx::isEnabled() + + inline bool ignoreC4127(bool _x) + { + return _x; + } +#define BX_IGNORE_C4127(_x) bx::ignoreC4127(!!(_x) ) + + template + inline void xchg(Ty& _a, Ty& _b) + { + Ty tmp = _a; _a = _b; _b = tmp; + } + + /// Check if pointer is aligned. _align must be power of two. + inline bool isPtrAligned(const void* _ptr, size_t _align) + { + union { const void* ptr; size_t addr; } un; + un.ptr = _ptr; + return 0 == (un.addr & (_align-1) ); + } + +} // namespace bx + +// Annoying C++0x stuff.. +namespace std { namespace tr1 {}; using namespace tr1; } + +#endif // BX_H_HEADER_GUARD diff --git a/deps/include/bx/cl.h b/deps/include/bx/cl.h new file mode 100644 index 0000000..d42ff40 --- /dev/null +++ b/deps/include/bx/cl.h @@ -0,0 +1,925 @@ +/* + * Copyright 2010-2015 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#ifndef BX_CL_H_HEADER_GUARD +#define BX_CL_H_HEADER_GUARD + +/// To implement OpenCL dynamic loading, define BX_CL_IMPLEMENTATION and +/// #include into .cpp file. +/// +/// To use it, just #include without defining BX_CL_IMPLEMENTATION. +/// To load dynamic library call bx::clLoad(), to unload it call bx::clUnload. + +namespace bx +{ + /// Load OpenCL dynamic library. + /// + /// Returns internal reference count. If library is not available + /// returns 0. + /// + int32_t clLoad(); + + /// Unload OpenCL dynamic library. + /// + /// Returns internal reference count. When reference count reaches 0 + /// library is fully unloaded. + /// + int32_t clUnload(); + +} // namespace bx + +#if defined(BX_CL_IMPLEMENTATION) && defined(__OPENCL_CL_H) +# error message("CL/cl.h is already included, it cannot be included before bx/cl.h header when BX_CL_IMPLEMENTATION is defined!") +#endif // defined(BX_CL_IMPLEMENTATION) && defined(__OPENCL_CL_H) + +#ifndef __OPENCL_CL_H +#define __OPENCL_CL_H + +// BK - CL/cl.h header begin ------------------------------------------------->8 + +/******************************************************************************* + * Copyright (c) 2008 - 2012 The Khronos Group Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and/or associated documentation files (the + * "Materials"), to deal in the Materials without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Materials, and to + * permit persons to whom the Materials are 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 Materials. + * + * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. + ******************************************************************************/ + +#ifdef __APPLE__ +#include +#else +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************/ + +typedef struct _cl_platform_id * cl_platform_id; +typedef struct _cl_device_id * cl_device_id; +typedef struct _cl_context * cl_context; +typedef struct _cl_command_queue * cl_command_queue; +typedef struct _cl_mem * cl_mem; +typedef struct _cl_program * cl_program; +typedef struct _cl_kernel * cl_kernel; +typedef struct _cl_event * cl_event; +typedef struct _cl_sampler * cl_sampler; + +typedef cl_uint cl_bool; /* WARNING! Unlike cl_ types in cl_platform.h, cl_bool is not guaranteed to be the same size as the bool in kernels. */ +typedef cl_ulong cl_bitfield; +typedef cl_bitfield cl_device_type; +typedef cl_uint cl_platform_info; +typedef cl_uint cl_device_info; +typedef cl_bitfield cl_device_fp_config; +typedef cl_uint cl_device_mem_cache_type; +typedef cl_uint cl_device_local_mem_type; +typedef cl_bitfield cl_device_exec_capabilities; +typedef cl_bitfield cl_command_queue_properties; +typedef intptr_t cl_device_partition_property; +typedef cl_bitfield cl_device_affinity_domain; + +typedef intptr_t cl_context_properties; +typedef cl_uint cl_context_info; +typedef cl_uint cl_command_queue_info; +typedef cl_uint cl_channel_order; +typedef cl_uint cl_channel_type; +typedef cl_bitfield cl_mem_flags; +typedef cl_uint cl_mem_object_type; +typedef cl_uint cl_mem_info; +typedef cl_bitfield cl_mem_migration_flags; +typedef cl_uint cl_image_info; +typedef cl_uint cl_buffer_create_type; +typedef cl_uint cl_addressing_mode; +typedef cl_uint cl_filter_mode; +typedef cl_uint cl_sampler_info; +typedef cl_bitfield cl_map_flags; +typedef cl_uint cl_program_info; +typedef cl_uint cl_program_build_info; +typedef cl_uint cl_program_binary_type; +typedef cl_int cl_build_status; +typedef cl_uint cl_kernel_info; +typedef cl_uint cl_kernel_arg_info; +typedef cl_uint cl_kernel_arg_address_qualifier; +typedef cl_uint cl_kernel_arg_access_qualifier; +typedef cl_bitfield cl_kernel_arg_type_qualifier; +typedef cl_uint cl_kernel_work_group_info; +typedef cl_uint cl_event_info; +typedef cl_uint cl_command_type; +typedef cl_uint cl_profiling_info; + + +typedef struct _cl_image_format { + cl_channel_order image_channel_order; + cl_channel_type image_channel_data_type; +} cl_image_format; + +typedef struct _cl_image_desc { + cl_mem_object_type image_type; + size_t image_width; + size_t image_height; + size_t image_depth; + size_t image_array_size; + size_t image_row_pitch; + size_t image_slice_pitch; + cl_uint num_mip_levels; + cl_uint num_samples; + cl_mem buffer; +} cl_image_desc; + +typedef struct _cl_buffer_region { + size_t origin; + size_t size; +} cl_buffer_region; + + +/******************************************************************************/ + +/* Error Codes */ +#define CL_SUCCESS 0 +#define CL_DEVICE_NOT_FOUND -1 +#define CL_DEVICE_NOT_AVAILABLE -2 +#define CL_COMPILER_NOT_AVAILABLE -3 +#define CL_MEM_OBJECT_ALLOCATION_FAILURE -4 +#define CL_OUT_OF_RESOURCES -5 +#define CL_OUT_OF_HOST_MEMORY -6 +#define CL_PROFILING_INFO_NOT_AVAILABLE -7 +#define CL_MEM_COPY_OVERLAP -8 +#define CL_IMAGE_FORMAT_MISMATCH -9 +#define CL_IMAGE_FORMAT_NOT_SUPPORTED -10 +#define CL_BUILD_PROGRAM_FAILURE -11 +#define CL_MAP_FAILURE -12 +#define CL_MISALIGNED_SUB_BUFFER_OFFSET -13 +#define CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST -14 +#define CL_COMPILE_PROGRAM_FAILURE -15 +#define CL_LINKER_NOT_AVAILABLE -16 +#define CL_LINK_PROGRAM_FAILURE -17 +#define CL_DEVICE_PARTITION_FAILED -18 +#define CL_KERNEL_ARG_INFO_NOT_AVAILABLE -19 + +#define CL_INVALID_VALUE -30 +#define CL_INVALID_DEVICE_TYPE -31 +#define CL_INVALID_PLATFORM -32 +#define CL_INVALID_DEVICE -33 +#define CL_INVALID_CONTEXT -34 +#define CL_INVALID_QUEUE_PROPERTIES -35 +#define CL_INVALID_COMMAND_QUEUE -36 +#define CL_INVALID_HOST_PTR -37 +#define CL_INVALID_MEM_OBJECT -38 +#define CL_INVALID_IMAGE_FORMAT_DESCRIPTOR -39 +#define CL_INVALID_IMAGE_SIZE -40 +#define CL_INVALID_SAMPLER -41 +#define CL_INVALID_BINARY -42 +#define CL_INVALID_BUILD_OPTIONS -43 +#define CL_INVALID_PROGRAM -44 +#define CL_INVALID_PROGRAM_EXECUTABLE -45 +#define CL_INVALID_KERNEL_NAME -46 +#define CL_INVALID_KERNEL_DEFINITION -47 +#define CL_INVALID_KERNEL -48 +#define CL_INVALID_ARG_INDEX -49 +#define CL_INVALID_ARG_VALUE -50 +#define CL_INVALID_ARG_SIZE -51 +#define CL_INVALID_KERNEL_ARGS -52 +#define CL_INVALID_WORK_DIMENSION -53 +#define CL_INVALID_WORK_GROUP_SIZE -54 +#define CL_INVALID_WORK_ITEM_SIZE -55 +#define CL_INVALID_GLOBAL_OFFSET -56 +#define CL_INVALID_EVENT_WAIT_LIST -57 +#define CL_INVALID_EVENT -58 +#define CL_INVALID_OPERATION -59 +#define CL_INVALID_GL_OBJECT -60 +#define CL_INVALID_BUFFER_SIZE -61 +#define CL_INVALID_MIP_LEVEL -62 +#define CL_INVALID_GLOBAL_WORK_SIZE -63 +#define CL_INVALID_PROPERTY -64 +#define CL_INVALID_IMAGE_DESCRIPTOR -65 +#define CL_INVALID_COMPILER_OPTIONS -66 +#define CL_INVALID_LINKER_OPTIONS -67 +#define CL_INVALID_DEVICE_PARTITION_COUNT -68 + +/* OpenCL Version */ +#define CL_VERSION_1_0 1 +#define CL_VERSION_1_1 1 +#define CL_VERSION_1_2 1 + +/* cl_bool */ +#define CL_FALSE 0 +#define CL_TRUE 1 +#define CL_BLOCKING CL_TRUE +#define CL_NON_BLOCKING CL_FALSE + +/* cl_platform_info */ +#define CL_PLATFORM_PROFILE 0x0900 +#define CL_PLATFORM_VERSION 0x0901 +#define CL_PLATFORM_NAME 0x0902 +#define CL_PLATFORM_VENDOR 0x0903 +#define CL_PLATFORM_EXTENSIONS 0x0904 + +/* cl_device_type - bitfield */ +#define CL_DEVICE_TYPE_DEFAULT (1 << 0) +#define CL_DEVICE_TYPE_CPU (1 << 1) +#define CL_DEVICE_TYPE_GPU (1 << 2) +#define CL_DEVICE_TYPE_ACCELERATOR (1 << 3) +#define CL_DEVICE_TYPE_CUSTOM (1 << 4) +#define CL_DEVICE_TYPE_ALL 0xFFFFFFFF + +/* cl_device_info */ +#define CL_DEVICE_TYPE 0x1000 +#define CL_DEVICE_VENDOR_ID 0x1001 +#define CL_DEVICE_MAX_COMPUTE_UNITS 0x1002 +#define CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS 0x1003 +#define CL_DEVICE_MAX_WORK_GROUP_SIZE 0x1004 +#define CL_DEVICE_MAX_WORK_ITEM_SIZES 0x1005 +#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR 0x1006 +#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT 0x1007 +#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT 0x1008 +#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG 0x1009 +#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT 0x100A +#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE 0x100B +#define CL_DEVICE_MAX_CLOCK_FREQUENCY 0x100C +#define CL_DEVICE_ADDRESS_BITS 0x100D +#define CL_DEVICE_MAX_READ_IMAGE_ARGS 0x100E +#define CL_DEVICE_MAX_WRITE_IMAGE_ARGS 0x100F +#define CL_DEVICE_MAX_MEM_ALLOC_SIZE 0x1010 +#define CL_DEVICE_IMAGE2D_MAX_WIDTH 0x1011 +#define CL_DEVICE_IMAGE2D_MAX_HEIGHT 0x1012 +#define CL_DEVICE_IMAGE3D_MAX_WIDTH 0x1013 +#define CL_DEVICE_IMAGE3D_MAX_HEIGHT 0x1014 +#define CL_DEVICE_IMAGE3D_MAX_DEPTH 0x1015 +#define CL_DEVICE_IMAGE_SUPPORT 0x1016 +#define CL_DEVICE_MAX_PARAMETER_SIZE 0x1017 +#define CL_DEVICE_MAX_SAMPLERS 0x1018 +#define CL_DEVICE_MEM_BASE_ADDR_ALIGN 0x1019 +#define CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE 0x101A +#define CL_DEVICE_SINGLE_FP_CONFIG 0x101B +#define CL_DEVICE_GLOBAL_MEM_CACHE_TYPE 0x101C +#define CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE 0x101D +#define CL_DEVICE_GLOBAL_MEM_CACHE_SIZE 0x101E +#define CL_DEVICE_GLOBAL_MEM_SIZE 0x101F +#define CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE 0x1020 +#define CL_DEVICE_MAX_CONSTANT_ARGS 0x1021 +#define CL_DEVICE_LOCAL_MEM_TYPE 0x1022 +#define CL_DEVICE_LOCAL_MEM_SIZE 0x1023 +#define CL_DEVICE_ERROR_CORRECTION_SUPPORT 0x1024 +#define CL_DEVICE_PROFILING_TIMER_RESOLUTION 0x1025 +#define CL_DEVICE_ENDIAN_LITTLE 0x1026 +#define CL_DEVICE_AVAILABLE 0x1027 +#define CL_DEVICE_COMPILER_AVAILABLE 0x1028 +#define CL_DEVICE_EXECUTION_CAPABILITIES 0x1029 +#define CL_DEVICE_QUEUE_PROPERTIES 0x102A +#define CL_DEVICE_NAME 0x102B +#define CL_DEVICE_VENDOR 0x102C +#define CL_DRIVER_VERSION 0x102D +#define CL_DEVICE_PROFILE 0x102E +#define CL_DEVICE_VERSION 0x102F +#define CL_DEVICE_EXTENSIONS 0x1030 +#define CL_DEVICE_PLATFORM 0x1031 +#define CL_DEVICE_DOUBLE_FP_CONFIG 0x1032 +/* 0x1033 reserved for CL_DEVICE_HALF_FP_CONFIG */ +#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF 0x1034 +#define CL_DEVICE_HOST_UNIFIED_MEMORY 0x1035 +#define CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR 0x1036 +#define CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT 0x1037 +#define CL_DEVICE_NATIVE_VECTOR_WIDTH_INT 0x1038 +#define CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG 0x1039 +#define CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT 0x103A +#define CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE 0x103B +#define CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF 0x103C +#define CL_DEVICE_OPENCL_C_VERSION 0x103D +#define CL_DEVICE_LINKER_AVAILABLE 0x103E +#define CL_DEVICE_BUILT_IN_KERNELS 0x103F +#define CL_DEVICE_IMAGE_MAX_BUFFER_SIZE 0x1040 +#define CL_DEVICE_IMAGE_MAX_ARRAY_SIZE 0x1041 +#define CL_DEVICE_PARENT_DEVICE 0x1042 +#define CL_DEVICE_PARTITION_MAX_SUB_DEVICES 0x1043 +#define CL_DEVICE_PARTITION_PROPERTIES 0x1044 +#define CL_DEVICE_PARTITION_AFFINITY_DOMAIN 0x1045 +#define CL_DEVICE_PARTITION_TYPE 0x1046 +#define CL_DEVICE_REFERENCE_COUNT 0x1047 +#define CL_DEVICE_PREFERRED_INTEROP_USER_SYNC 0x1048 +#define CL_DEVICE_PRINTF_BUFFER_SIZE 0x1049 +#define CL_DEVICE_IMAGE_PITCH_ALIGNMENT 0x104A +#define CL_DEVICE_IMAGE_BASE_ADDRESS_ALIGNMENT 0x104B + +/* cl_device_fp_config - bitfield */ +#define CL_FP_DENORM (1 << 0) +#define CL_FP_INF_NAN (1 << 1) +#define CL_FP_ROUND_TO_NEAREST (1 << 2) +#define CL_FP_ROUND_TO_ZERO (1 << 3) +#define CL_FP_ROUND_TO_INF (1 << 4) +#define CL_FP_FMA (1 << 5) +#define CL_FP_SOFT_FLOAT (1 << 6) +#define CL_FP_CORRECTLY_ROUNDED_DIVIDE_SQRT (1 << 7) + +/* cl_device_mem_cache_type */ +#define CL_NONE 0x0 +#define CL_READ_ONLY_CACHE 0x1 +#define CL_READ_WRITE_CACHE 0x2 + +/* cl_device_local_mem_type */ +#define CL_LOCAL 0x1 +#define CL_GLOBAL 0x2 + +/* cl_device_exec_capabilities - bitfield */ +#define CL_EXEC_KERNEL (1 << 0) +#define CL_EXEC_NATIVE_KERNEL (1 << 1) + +/* cl_command_queue_properties - bitfield */ +#define CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE (1 << 0) +#define CL_QUEUE_PROFILING_ENABLE (1 << 1) + +/* cl_context_info */ +#define CL_CONTEXT_REFERENCE_COUNT 0x1080 +#define CL_CONTEXT_DEVICES 0x1081 +#define CL_CONTEXT_PROPERTIES 0x1082 +#define CL_CONTEXT_NUM_DEVICES 0x1083 + +/* cl_context_properties */ +#define CL_CONTEXT_PLATFORM 0x1084 +#define CL_CONTEXT_INTEROP_USER_SYNC 0x1085 + +/* cl_device_partition_property */ +#define CL_DEVICE_PARTITION_EQUALLY 0x1086 +#define CL_DEVICE_PARTITION_BY_COUNTS 0x1087 +#define CL_DEVICE_PARTITION_BY_COUNTS_LIST_END 0x0 +#define CL_DEVICE_PARTITION_BY_AFFINITY_DOMAIN 0x1088 + +/* cl_device_affinity_domain */ +#define CL_DEVICE_AFFINITY_DOMAIN_NUMA (1 << 0) +#define CL_DEVICE_AFFINITY_DOMAIN_L4_CACHE (1 << 1) +#define CL_DEVICE_AFFINITY_DOMAIN_L3_CACHE (1 << 2) +#define CL_DEVICE_AFFINITY_DOMAIN_L2_CACHE (1 << 3) +#define CL_DEVICE_AFFINITY_DOMAIN_L1_CACHE (1 << 4) +#define CL_DEVICE_AFFINITY_DOMAIN_NEXT_PARTITIONABLE (1 << 5) + +/* cl_command_queue_info */ +#define CL_QUEUE_CONTEXT 0x1090 +#define CL_QUEUE_DEVICE 0x1091 +#define CL_QUEUE_REFERENCE_COUNT 0x1092 +#define CL_QUEUE_PROPERTIES 0x1093 + +/* cl_mem_flags - bitfield */ +#define CL_MEM_READ_WRITE (1 << 0) +#define CL_MEM_WRITE_ONLY (1 << 1) +#define CL_MEM_READ_ONLY (1 << 2) +#define CL_MEM_USE_HOST_PTR (1 << 3) +#define CL_MEM_ALLOC_HOST_PTR (1 << 4) +#define CL_MEM_COPY_HOST_PTR (1 << 5) +// reserved (1 << 6) +#define CL_MEM_HOST_WRITE_ONLY (1 << 7) +#define CL_MEM_HOST_READ_ONLY (1 << 8) +#define CL_MEM_HOST_NO_ACCESS (1 << 9) + +/* cl_mem_migration_flags - bitfield */ +#define CL_MIGRATE_MEM_OBJECT_HOST (1 << 0) +#define CL_MIGRATE_MEM_OBJECT_CONTENT_UNDEFINED (1 << 1) + +/* cl_channel_order */ +#define CL_R 0x10B0 +#define CL_A 0x10B1 +#define CL_RG 0x10B2 +#define CL_RA 0x10B3 +#define CL_RGB 0x10B4 +#define CL_RGBA 0x10B5 +#define CL_BGRA 0x10B6 +#define CL_ARGB 0x10B7 +#define CL_INTENSITY 0x10B8 +#define CL_LUMINANCE 0x10B9 +#define CL_Rx 0x10BA +#define CL_RGx 0x10BB +#define CL_RGBx 0x10BC +#define CL_DEPTH 0x10BD +#define CL_DEPTH_STENCIL 0x10BE + +/* cl_channel_type */ +#define CL_SNORM_INT8 0x10D0 +#define CL_SNORM_INT16 0x10D1 +#define CL_UNORM_INT8 0x10D2 +#define CL_UNORM_INT16 0x10D3 +#define CL_UNORM_SHORT_565 0x10D4 +#define CL_UNORM_SHORT_555 0x10D5 +#define CL_UNORM_INT_101010 0x10D6 +#define CL_SIGNED_INT8 0x10D7 +#define CL_SIGNED_INT16 0x10D8 +#define CL_SIGNED_INT32 0x10D9 +#define CL_UNSIGNED_INT8 0x10DA +#define CL_UNSIGNED_INT16 0x10DB +#define CL_UNSIGNED_INT32 0x10DC +#define CL_HALF_FLOAT 0x10DD +#define CL_FLOAT 0x10DE +#define CL_UNORM_INT24 0x10DF + +/* cl_mem_object_type */ +#define CL_MEM_OBJECT_BUFFER 0x10F0 +#define CL_MEM_OBJECT_IMAGE2D 0x10F1 +#define CL_MEM_OBJECT_IMAGE3D 0x10F2 +#define CL_MEM_OBJECT_IMAGE2D_ARRAY 0x10F3 +#define CL_MEM_OBJECT_IMAGE1D 0x10F4 +#define CL_MEM_OBJECT_IMAGE1D_ARRAY 0x10F5 +#define CL_MEM_OBJECT_IMAGE1D_BUFFER 0x10F6 + +/* cl_mem_info */ +#define CL_MEM_TYPE 0x1100 +#define CL_MEM_FLAGS 0x1101 +#define CL_MEM_SIZE 0x1102 +#define CL_MEM_HOST_PTR 0x1103 +#define CL_MEM_MAP_COUNT 0x1104 +#define CL_MEM_REFERENCE_COUNT 0x1105 +#define CL_MEM_CONTEXT 0x1106 +#define CL_MEM_ASSOCIATED_MEMOBJECT 0x1107 +#define CL_MEM_OFFSET 0x1108 + +/* cl_image_info */ +#define CL_IMAGE_FORMAT 0x1110 +#define CL_IMAGE_ELEMENT_SIZE 0x1111 +#define CL_IMAGE_ROW_PITCH 0x1112 +#define CL_IMAGE_SLICE_PITCH 0x1113 +#define CL_IMAGE_WIDTH 0x1114 +#define CL_IMAGE_HEIGHT 0x1115 +#define CL_IMAGE_DEPTH 0x1116 +#define CL_IMAGE_ARRAY_SIZE 0x1117 +#define CL_IMAGE_BUFFER 0x1118 +#define CL_IMAGE_NUM_MIP_LEVELS 0x1119 +#define CL_IMAGE_NUM_SAMPLES 0x111A + +/* cl_addressing_mode */ +#define CL_ADDRESS_NONE 0x1130 +#define CL_ADDRESS_CLAMP_TO_EDGE 0x1131 +#define CL_ADDRESS_CLAMP 0x1132 +#define CL_ADDRESS_REPEAT 0x1133 +#define CL_ADDRESS_MIRRORED_REPEAT 0x1134 + +/* cl_filter_mode */ +#define CL_FILTER_NEAREST 0x1140 +#define CL_FILTER_LINEAR 0x1141 + +/* cl_sampler_info */ +#define CL_SAMPLER_REFERENCE_COUNT 0x1150 +#define CL_SAMPLER_CONTEXT 0x1151 +#define CL_SAMPLER_NORMALIZED_COORDS 0x1152 +#define CL_SAMPLER_ADDRESSING_MODE 0x1153 +#define CL_SAMPLER_FILTER_MODE 0x1154 + +/* cl_map_flags - bitfield */ +#define CL_MAP_READ (1 << 0) +#define CL_MAP_WRITE (1 << 1) +#define CL_MAP_WRITE_INVALIDATE_REGION (1 << 2) + +/* cl_program_info */ +#define CL_PROGRAM_REFERENCE_COUNT 0x1160 +#define CL_PROGRAM_CONTEXT 0x1161 +#define CL_PROGRAM_NUM_DEVICES 0x1162 +#define CL_PROGRAM_DEVICES 0x1163 +#define CL_PROGRAM_SOURCE 0x1164 +#define CL_PROGRAM_BINARY_SIZES 0x1165 +#define CL_PROGRAM_BINARIES 0x1166 +#define CL_PROGRAM_NUM_KERNELS 0x1167 +#define CL_PROGRAM_KERNEL_NAMES 0x1168 + +/* cl_program_build_info */ +#define CL_PROGRAM_BUILD_STATUS 0x1181 +#define CL_PROGRAM_BUILD_OPTIONS 0x1182 +#define CL_PROGRAM_BUILD_LOG 0x1183 +#define CL_PROGRAM_BINARY_TYPE 0x1184 + +/* cl_program_binary_type */ +#define CL_PROGRAM_BINARY_TYPE_NONE 0x0 +#define CL_PROGRAM_BINARY_TYPE_COMPILED_OBJECT 0x1 +#define CL_PROGRAM_BINARY_TYPE_LIBRARY 0x2 +#define CL_PROGRAM_BINARY_TYPE_EXECUTABLE 0x4 + +/* cl_build_status */ +#define CL_BUILD_SUCCESS 0 +#define CL_BUILD_NONE -1 +#define CL_BUILD_ERROR -2 +#define CL_BUILD_IN_PROGRESS -3 + +/* cl_kernel_info */ +#define CL_KERNEL_FUNCTION_NAME 0x1190 +#define CL_KERNEL_NUM_ARGS 0x1191 +#define CL_KERNEL_REFERENCE_COUNT 0x1192 +#define CL_KERNEL_CONTEXT 0x1193 +#define CL_KERNEL_PROGRAM 0x1194 +#define CL_KERNEL_ATTRIBUTES 0x1195 + +/* cl_kernel_arg_info */ +#define CL_KERNEL_ARG_ADDRESS_QUALIFIER 0x1196 +#define CL_KERNEL_ARG_ACCESS_QUALIFIER 0x1197 +#define CL_KERNEL_ARG_TYPE_NAME 0x1198 +#define CL_KERNEL_ARG_TYPE_QUALIFIER 0x1199 +#define CL_KERNEL_ARG_NAME 0x119A + +/* cl_kernel_arg_address_qualifier */ +#define CL_KERNEL_ARG_ADDRESS_GLOBAL 0x119B +#define CL_KERNEL_ARG_ADDRESS_LOCAL 0x119C +#define CL_KERNEL_ARG_ADDRESS_CONSTANT 0x119D +#define CL_KERNEL_ARG_ADDRESS_PRIVATE 0x119E + +/* cl_kernel_arg_access_qualifier */ +#define CL_KERNEL_ARG_ACCESS_READ_ONLY 0x11A0 +#define CL_KERNEL_ARG_ACCESS_WRITE_ONLY 0x11A1 +#define CL_KERNEL_ARG_ACCESS_READ_WRITE 0x11A2 +#define CL_KERNEL_ARG_ACCESS_NONE 0x11A3 + +/* cl_kernel_arg_type_qualifer */ +#define CL_KERNEL_ARG_TYPE_NONE 0 +#define CL_KERNEL_ARG_TYPE_CONST (1 << 0) +#define CL_KERNEL_ARG_TYPE_RESTRICT (1 << 1) +#define CL_KERNEL_ARG_TYPE_VOLATILE (1 << 2) + +/* cl_kernel_work_group_info */ +#define CL_KERNEL_WORK_GROUP_SIZE 0x11B0 +#define CL_KERNEL_COMPILE_WORK_GROUP_SIZE 0x11B1 +#define CL_KERNEL_LOCAL_MEM_SIZE 0x11B2 +#define CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE 0x11B3 +#define CL_KERNEL_PRIVATE_MEM_SIZE 0x11B4 +#define CL_KERNEL_GLOBAL_WORK_SIZE 0x11B5 + +/* cl_event_info */ +#define CL_EVENT_COMMAND_QUEUE 0x11D0 +#define CL_EVENT_COMMAND_TYPE 0x11D1 +#define CL_EVENT_REFERENCE_COUNT 0x11D2 +#define CL_EVENT_COMMAND_EXECUTION_STATUS 0x11D3 +#define CL_EVENT_CONTEXT 0x11D4 + +/* cl_command_type */ +#define CL_COMMAND_NDRANGE_KERNEL 0x11F0 +#define CL_COMMAND_TASK 0x11F1 +#define CL_COMMAND_NATIVE_KERNEL 0x11F2 +#define CL_COMMAND_READ_BUFFER 0x11F3 +#define CL_COMMAND_WRITE_BUFFER 0x11F4 +#define CL_COMMAND_COPY_BUFFER 0x11F5 +#define CL_COMMAND_READ_IMAGE 0x11F6 +#define CL_COMMAND_WRITE_IMAGE 0x11F7 +#define CL_COMMAND_COPY_IMAGE 0x11F8 +#define CL_COMMAND_COPY_IMAGE_TO_BUFFER 0x11F9 +#define CL_COMMAND_COPY_BUFFER_TO_IMAGE 0x11FA +#define CL_COMMAND_MAP_BUFFER 0x11FB +#define CL_COMMAND_MAP_IMAGE 0x11FC +#define CL_COMMAND_UNMAP_MEM_OBJECT 0x11FD +#define CL_COMMAND_MARKER 0x11FE +#define CL_COMMAND_ACQUIRE_GL_OBJECTS 0x11FF +#define CL_COMMAND_RELEASE_GL_OBJECTS 0x1200 +#define CL_COMMAND_READ_BUFFER_RECT 0x1201 +#define CL_COMMAND_WRITE_BUFFER_RECT 0x1202 +#define CL_COMMAND_COPY_BUFFER_RECT 0x1203 +#define CL_COMMAND_USER 0x1204 +#define CL_COMMAND_BARRIER 0x1205 +#define CL_COMMAND_MIGRATE_MEM_OBJECTS 0x1206 +#define CL_COMMAND_FILL_BUFFER 0x1207 +#define CL_COMMAND_FILL_IMAGE 0x1208 + +/* command execution status */ +#define CL_COMPLETE 0x0 +#define CL_RUNNING 0x1 +#define CL_SUBMITTED 0x2 +#define CL_QUEUED 0x3 + +/* cl_buffer_create_type */ +#define CL_BUFFER_CREATE_TYPE_REGION 0x1220 + +/* cl_profiling_info */ +#define CL_PROFILING_COMMAND_QUEUED 0x1280 +#define CL_PROFILING_COMMAND_SUBMIT 0x1281 +#define CL_PROFILING_COMMAND_START 0x1282 +#define CL_PROFILING_COMMAND_END 0x1283 + +#ifdef __cplusplus +} //extern "C" +#endif + +// BK - CL/cl.h header end --------------------------------------------------->8 + +// 1.1 +typedef cl_int (CL_API_CALL* PFNCLGETPLATFORMIDSPROC)(cl_uint, cl_platform_id*, cl_uint*); +typedef cl_int (CL_API_CALL* PFNCLGETPLATFORMINFOPROC)(cl_platform_id, cl_platform_info, size_t, void*, size_t*); +typedef cl_int (CL_API_CALL* PFNCLGETDEVICEINFOPROC)(cl_device_id, cl_device_info, size_t, void*, size_t*); +typedef cl_int (CL_API_CALL* PFNCLGETDEVICEIDSPROC)(cl_platform_id, cl_device_type, cl_uint, cl_device_id*, cl_uint*); +typedef cl_context (CL_API_CALL* PFNCLCREATECONTEXTPROC)(const cl_context_properties*, cl_uint, const cl_device_id*, void (CL_CALLBACK*)(const char*, const void*, size_t, void*), void*, cl_int*); +typedef cl_context (CL_API_CALL* PFNCLCREATECONTEXTFROMTYPEPROC)(const cl_context_properties *, cl_device_type, void (CL_CALLBACK*)(const char*, const void*, size_t, void*), void*, cl_int*); +typedef cl_int (CL_API_CALL* PFNCLRETAINCONTEXTPROC)(cl_context); +typedef cl_int (CL_API_CALL* PFNCLRELEASECONTEXTPROC)(cl_context); +typedef cl_int (CL_API_CALL* PFNCLGETCONTEXTINFOPROC)(cl_context, cl_context_info, size_t, void*, size_t*); +typedef cl_command_queue (CL_API_CALL* PFNCLCREATECOMMANDQUEUEPROC)(cl_context, cl_device_id, cl_command_queue_properties, cl_int*); +typedef cl_int (CL_API_CALL* PFNCLRETAINCOMMANDQUEUEPROC)(cl_command_queue); +typedef cl_int (CL_API_CALL* PFNCLRELEASECOMMANDQUEUEPROC)(cl_command_queue); +typedef cl_int (CL_API_CALL* PFNCLGETCOMMANDQUEUEINFOPROC)(cl_command_queue, cl_command_queue_info, size_t, void*, size_t*); +typedef cl_mem (CL_API_CALL* PFNCLCREATEBUFFERPROC)(cl_context, cl_mem_flags, size_t, void*, cl_int*); +typedef cl_int (CL_API_CALL* PFNCLRETAINMEMOBJECTPROC)(cl_mem); +typedef cl_int (CL_API_CALL* PFNCLRELEASEMEMOBJECTPROC)(cl_mem); +typedef cl_int (CL_API_CALL* PFNCLGETSUPPORTEDIMAGEFORMATSPROC)(cl_context, cl_mem_flags, cl_mem_object_type, cl_uint, cl_image_format*, cl_uint*); +typedef cl_int (CL_API_CALL* PFNCLGETMEMOBJECTINFOPROC)(cl_mem, cl_mem_info, size_t, void*, size_t*); +typedef cl_int (CL_API_CALL* PFNCLGETIMAGEINFOPROC)(cl_mem, cl_image_info, size_t, void*, size_t*); +typedef cl_sampler (CL_API_CALL* PFNCLCREATESAMPLERPROC)(cl_context, cl_bool, cl_addressing_mode, cl_filter_mode, cl_int*); +typedef cl_int (CL_API_CALL* PFNCLRETAINSAMPLERPROC)(cl_sampler); +typedef cl_int (CL_API_CALL* PFNCLRELEASESAMPLERPROC)(cl_sampler); +typedef cl_int (CL_API_CALL* PFNCLGETSAMPLERINFOPROC)(cl_sampler, cl_sampler_info, size_t, void*, size_t*); +typedef cl_program (CL_API_CALL* PFNCLCREATEPROGRAMWITHSOURCEPROC)(cl_context, cl_uint, const char**, const size_t*, cl_int*); +typedef cl_program (CL_API_CALL* PFNCLCREATEPROGRAMWITHBINARYPROC)(cl_context, cl_uint, const cl_device_id*, const size_t*, const unsigned char**, cl_int*, cl_int*); +typedef cl_int (CL_API_CALL* PFNCLRETAINPROGRAMPROC)(cl_program); +typedef cl_int (CL_API_CALL* PFNCLRELEASEPROGRAMPROC)(cl_program); +typedef cl_int (CL_API_CALL* PFNCLBUILDPROGRAMPROC)(cl_program, cl_uint, const cl_device_id *, const char *, void (CL_CALLBACK*)(cl_program, void*), void*); +typedef cl_int (CL_API_CALL* PFNCLGETPROGRAMINFOPROC)(cl_program, cl_program_info, size_t, void*, size_t*); +typedef cl_int (CL_API_CALL* PFNCLGETPROGRAMBUILDINFOPROC)(cl_program, cl_device_id, cl_program_build_info, size_t, void*, size_t*); +typedef cl_kernel (CL_API_CALL* PFNCLCREATEKERNELPROC)(cl_program, const char*, cl_int*); +typedef cl_int (CL_API_CALL* PFNCLCREATEKERNELSINPROGRAMPROC)(cl_program, cl_uint, cl_kernel*, cl_uint*); +typedef cl_int (CL_API_CALL* PFNCLRETAINKERNELPROC)(cl_kernel); +typedef cl_int (CL_API_CALL* PFNCLRELEASEKERNELPROC)(cl_kernel); +typedef cl_int (CL_API_CALL* PFNCLSETKERNELARGPROC)(cl_kernel, cl_uint, size_t, const void*); +typedef cl_int (CL_API_CALL* PFNCLGETKERNELINFOPROC)(cl_kernel, cl_kernel_info, size_t, void*, size_t*); +typedef cl_int (CL_API_CALL* PFNCLGETKERNELWORKGROUPINFOPROC)(cl_kernel, cl_device_id, cl_kernel_work_group_info, size_t, void*, size_t*); +typedef cl_int (CL_API_CALL* PFNCLWAITFOREVENTSPROC)(cl_uint, const cl_event*); +typedef cl_int (CL_API_CALL* PFNCLGETEVENTINFOPROC)(cl_event, cl_event_info, size_t, void*, size_t*); +typedef cl_int (CL_API_CALL* PFNCLRETAINEVENTPROC)(cl_event); +typedef cl_int (CL_API_CALL* PFNCLRELEASEEVENTPROC)(cl_event); +typedef cl_int (CL_API_CALL* PFNCLGETEVENTPROFILINGINFOPROC)(cl_event, cl_profiling_info, size_t, void*, size_t*); +typedef cl_int (CL_API_CALL* PFNCLFLUSHPROC)(cl_command_queue); +typedef cl_int (CL_API_CALL* PFNCLFINISHPROC)(cl_command_queue); +typedef cl_int (CL_API_CALL* PFNCLENQUEUEREADBUFFERPROC)(cl_command_queue, cl_mem, cl_bool, size_t, size_t, void*, cl_uint, const cl_event*, cl_event*); +typedef cl_int (CL_API_CALL* PFNCLENQUEUEWRITEBUFFERPROC)(cl_command_queue, cl_mem, cl_bool, size_t, size_t, const void*, cl_uint, const cl_event*, cl_event*); +typedef cl_int (CL_API_CALL* PFNCLENQUEUECOPYBUFFERPROC)(cl_command_queue, cl_mem, cl_mem, size_t, size_t, size_t, cl_uint, const cl_event*, cl_event*); +typedef cl_int (CL_API_CALL* PFNCLENQUEUEREADIMAGEPROC)(cl_command_queue, cl_mem, cl_bool, const size_t*, const size_t*, size_t, size_t, void*, cl_uint, const cl_event*, cl_event*); +typedef cl_int (CL_API_CALL* PFNCLENQUEUEWRITEIMAGEPROC)(cl_command_queue, cl_mem, cl_bool, const size_t*, const size_t*, size_t, size_t, const void*, cl_uint, const cl_event*, cl_event*); +typedef cl_int (CL_API_CALL* PFNCLENQUEUECOPYIMAGEPROC)(cl_command_queue, cl_mem, cl_mem, const size_t*, const size_t*, const size_t*, cl_uint, const cl_event*, cl_event*); +typedef cl_int (CL_API_CALL* PFNCLENQUEUECOPYIMAGETOBUFFERPROC)(cl_command_queue, cl_mem, cl_mem, const size_t*, const size_t*, size_t, cl_uint, const cl_event*, cl_event*); +typedef cl_int (CL_API_CALL* PFNCLENQUEUECOPYBUFFERTOIMAGEPROC)(cl_command_queue, cl_mem, cl_mem, size_t, const size_t*, const size_t*, cl_uint, const cl_event*, cl_event*); +typedef void (CL_API_CALL* PFNCLENQUEUEMAPBUFFERPROC)(cl_command_queue, cl_mem, cl_bool, cl_map_flags, size_t, size_t, cl_uint, const cl_event*, cl_event*, cl_int*); +typedef void (CL_API_CALL* PFNCLENQUEUEMAPIMAGEPROC)(cl_command_queue, cl_mem, cl_bool, cl_map_flags, const size_t *, const size_t *, size_t *, size_t *, cl_uint, const cl_event *, cl_event *, cl_int*); +typedef cl_int (CL_API_CALL* PFNCLENQUEUEUNMAPMEMOBJECTPROC)(cl_command_queue, cl_mem, void*, cl_uint, const cl_event*, cl_event*); +typedef cl_int (CL_API_CALL* PFNCLENQUEUENDRANGEKERNELPROC)(cl_command_queue, cl_kernel, cl_uint, const size_t*, const size_t*, const size_t*, cl_uint, const cl_event*, cl_event*); +typedef cl_int (CL_API_CALL* PFNCLENQUEUETASKPROC)(cl_command_queue, cl_kernel, cl_uint, const cl_event*, cl_event*); +typedef cl_int (CL_API_CALL* PFNCLENQUEUENATIVEKERNELPROC)(cl_command_queue, void (CL_CALLBACK*)(void*), void*, size_t, cl_uint, const cl_mem*, const void**, cl_uint, const cl_event*, cl_event*); + +// 1.1 +typedef cl_mem (CL_API_CALL* PFNCLCREATEIMAGE2DPROC)(cl_context, cl_mem_flags, const cl_image_format*, size_t, size_t, size_t, void*, cl_int*); +typedef cl_mem (CL_API_CALL* PFNCLCREATEIMAGE3DPROC)(cl_context, cl_mem_flags, const cl_image_format*, size_t, size_t, size_t, size_t, size_t, void*, cl_int*); +typedef cl_mem (CL_API_CALL* PFNCLCREATESUBBUFFERPROC)(cl_mem, cl_mem_flags, cl_buffer_create_type, const void*, cl_int*); +typedef cl_int (CL_API_CALL* PFNCLSETMEMOBJECTDESTRUCTORCALLBACKPROC)(cl_mem, void (CL_CALLBACK*)(cl_mem, void*), void*); +typedef cl_event (CL_API_CALL* PFNCLCREATEUSEREVENTPROC)(cl_context, cl_int*); +typedef cl_int (CL_API_CALL* PFNCLSETUSEREVENTSTATUSPROC)(cl_event, cl_int); +typedef cl_int (CL_API_CALL* PFNCLSETEVENTCALLBACKPROC)(cl_event, cl_int, void (CL_CALLBACK*)(cl_event, cl_int, void*), void*); +typedef cl_int (CL_API_CALL* PFNCLENQUEUEREADBUFFERRECTPROC)(cl_command_queue, cl_mem, cl_bool, const size_t *, const size_t *, const size_t *, size_t, size_t, size_t, size_t, void*, cl_uint, const cl_event*, cl_event*); +typedef cl_int (CL_API_CALL* PFNCLENQUEUEWRITEBUFFERRECTPROC)(cl_command_queue, cl_mem, cl_bool, const size_t *, const size_t *, const size_t *, size_t, size_t, size_t, size_t, const void*, cl_uint, const cl_event*, cl_event*); +typedef cl_int (CL_API_CALL* PFNCLENQUEUECOPYBUFFERRECTPROC)(cl_command_queue, cl_mem, cl_mem, const size_t*, const size_t*, const size_t*, size_t, size_t, size_t, size_t, cl_uint, const cl_event*, cl_event*); + +// 1.2 +typedef cl_int (CL_API_CALL* PFNCLCREATESUBDEVICESPROC)(cl_device_id, const cl_device_partition_property*, cl_uint, cl_device_id*, cl_uint*); +typedef cl_int (CL_API_CALL* PFNCLRETAINDEVICEPROC)(cl_device_id); +typedef cl_int (CL_API_CALL* PFNCLRELEASEDEVICEPROC)(cl_device_id); +typedef cl_mem (CL_API_CALL* PFNCLCREATEIMAGEPROC)(cl_context, cl_mem_flags, const cl_image_format*, const cl_image_desc*, void*, cl_int*); +typedef cl_program (CL_API_CALL* PFNCLCREATEPROGRAMWITHBUILTINKERNELSPROC)(cl_context, cl_uint, const cl_device_id*, const char*, cl_int*); +typedef cl_int (CL_API_CALL* PFNCLCOMPILEPROGRAMPROC)(cl_program, cl_uint, const cl_device_id*, const char*, cl_uint, const cl_program*, const char**, void (CL_CALLBACK*)(cl_program, void*), void*); +typedef cl_program (CL_API_CALL* PFNCLLINKPROGRAMPROC)(cl_context, cl_uint, const cl_device_id*, const char*, cl_uint, const cl_program*, void (CL_CALLBACK*)(cl_program, void*), void*, cl_int*); +typedef cl_int (CL_API_CALL* PFNCLUNLOADPLATFORMCOMPILERPROC)(cl_platform_id); +typedef cl_int (CL_API_CALL* PFNCLGETKERNELARGINFOPROC)(cl_kernel, cl_uint, cl_kernel_arg_info, size_t, void*, size_t*); +typedef cl_int (CL_API_CALL* PFNCLENQUEUEFILLBUFFERPROC)(cl_command_queue, cl_mem, const void*, size_t, size_t, size_t, cl_uint, const cl_event*, cl_event *); +typedef cl_int (CL_API_CALL* PFNCLENQUEUEFILLIMAGEPROC)(cl_command_queue, cl_mem, const void*, const size_t*, const size_t*, cl_uint, const cl_event*, cl_event*); +typedef cl_int (CL_API_CALL* PFNCLENQUEUEMIGRATEMEMOBJECTSPROC)(cl_command_queue, cl_uint, const cl_mem*, cl_mem_migration_flags, cl_uint, const cl_event *, cl_event*); +typedef cl_int (CL_API_CALL* PFNCLENQUEUEMARKERWITHWAITLISTPROC)(cl_command_queue, cl_uint, const cl_event*, cl_event*); +typedef cl_int (CL_API_CALL* PFNCLENQUEUEBARRIERWITHWAITLISTPROC)(cl_command_queue, cl_uint, const cl_event *, cl_event*); + +#define BX_CL_IMPORT_ALL_10 \ + /* Platform API */ \ + BX_CL_IMPORT_10(false, PFNCLGETPLATFORMIDSPROC, clGetPlatformIDs); \ + BX_CL_IMPORT_10(false, PFNCLGETPLATFORMINFOPROC, clGetPlatformInfo); \ + /* Device APIs */ \ + BX_CL_IMPORT_10(false, PFNCLGETDEVICEIDSPROC, clGetDeviceIDs); \ + BX_CL_IMPORT_10(false, PFNCLGETDEVICEINFOPROC, clGetDeviceInfo); \ + /* Context APIs */ \ + BX_CL_IMPORT_10(false, PFNCLCREATECONTEXTPROC, clCreateContext); \ + BX_CL_IMPORT_10(false, PFNCLCREATECONTEXTFROMTYPEPROC, clCreateContextFromType); \ + BX_CL_IMPORT_10(false, PFNCLRETAINCONTEXTPROC, clRetainContext); \ + BX_CL_IMPORT_10(false, PFNCLRELEASECONTEXTPROC, clReleaseContext); \ + BX_CL_IMPORT_10(false, PFNCLGETCONTEXTINFOPROC, clGetContextInfo); \ + /* Command Queue APIs */ \ + BX_CL_IMPORT_10(false, PFNCLCREATECOMMANDQUEUEPROC, clCreateCommandQueue); \ + BX_CL_IMPORT_10(false, PFNCLRETAINCOMMANDQUEUEPROC, clRetainCommandQueue); \ + BX_CL_IMPORT_10(false, PFNCLRELEASECOMMANDQUEUEPROC, clReleaseCommandQueue); \ + BX_CL_IMPORT_10(false, PFNCLGETCOMMANDQUEUEINFOPROC, clGetCommandQueueInfo); \ + /* Memory Object APIs */ \ + BX_CL_IMPORT_10(false, PFNCLCREATEBUFFERPROC, clCreateBuffer); \ + BX_CL_IMPORT_10(false, PFNCLRETAINMEMOBJECTPROC, clRetainMemObject); \ + BX_CL_IMPORT_10(false, PFNCLRELEASEMEMOBJECTPROC, clReleaseMemObject); \ + BX_CL_IMPORT_10(false, PFNCLGETSUPPORTEDIMAGEFORMATSPROC, clGetSupportedImageFormats); \ + BX_CL_IMPORT_10(false, PFNCLGETMEMOBJECTINFOPROC, clGetMemObjectInfo); \ + BX_CL_IMPORT_10(false, PFNCLGETIMAGEINFOPROC, clGetImageInfo); \ + /* Sampler APIs */ \ + BX_CL_IMPORT_10(false, PFNCLCREATESAMPLERPROC, clCreateSampler); \ + BX_CL_IMPORT_10(false, PFNCLRETAINSAMPLERPROC, clRetainSampler); \ + BX_CL_IMPORT_10(false, PFNCLRELEASESAMPLERPROC, clReleaseSampler); \ + BX_CL_IMPORT_10(false, PFNCLGETSAMPLERINFOPROC, clGetSamplerInfo); \ + /* Program Object APIs */ \ + BX_CL_IMPORT_10(false, PFNCLCREATEPROGRAMWITHSOURCEPROC, clCreateProgramWithSource); \ + BX_CL_IMPORT_10(false, PFNCLCREATEPROGRAMWITHBINARYPROC, clCreateProgramWithBinary); \ + BX_CL_IMPORT_10(false, PFNCLRETAINPROGRAMPROC, clRetainProgram); \ + BX_CL_IMPORT_10(false, PFNCLRELEASEPROGRAMPROC, clReleaseProgram); \ + BX_CL_IMPORT_10(false, PFNCLBUILDPROGRAMPROC, clBuildProgram); \ + BX_CL_IMPORT_10(false, PFNCLGETPROGRAMINFOPROC, clGetProgramInfo); \ + BX_CL_IMPORT_10(false, PFNCLGETPROGRAMBUILDINFOPROC, clGetProgramBuildInfo); \ + /* Kernel Object APIs */ \ + BX_CL_IMPORT_10(false, PFNCLCREATEKERNELPROC, clCreateKernel); \ + BX_CL_IMPORT_10(false, PFNCLCREATEKERNELSINPROGRAMPROC, clCreateKernelsInProgram); \ + BX_CL_IMPORT_10(false, PFNCLRETAINKERNELPROC, clRetainKernel); \ + BX_CL_IMPORT_10(false, PFNCLRELEASEKERNELPROC, clReleaseKernel); \ + BX_CL_IMPORT_10(false, PFNCLSETKERNELARGPROC, clSetKernelArg); \ + BX_CL_IMPORT_10(false, PFNCLGETKERNELINFOPROC, clGetKernelInfo); \ + BX_CL_IMPORT_10(false, PFNCLGETKERNELWORKGROUPINFOPROC, clGetKernelWorkGroupInfo); \ + /* Event Object APIs */ \ + BX_CL_IMPORT_10(false, PFNCLWAITFOREVENTSPROC, clWaitForEvents); \ + BX_CL_IMPORT_10(false, PFNCLGETEVENTINFOPROC, clGetEventInfo); \ + BX_CL_IMPORT_10(false, PFNCLRETAINEVENTPROC, clRetainEvent); \ + BX_CL_IMPORT_10(false, PFNCLRELEASEEVENTPROC, clReleaseEvent); \ + /* Profiling APIs */ \ + BX_CL_IMPORT_10(false, PFNCLGETEVENTPROFILINGINFOPROC, clGetEventProfilingInfo); \ + /* Flush and Finish APIs */ \ + BX_CL_IMPORT_10(false, PFNCLFLUSHPROC, clFlush); \ + BX_CL_IMPORT_10(false, PFNCLFINISHPROC, clFinish); \ + /* Enqueued Commands APIs */ \ + BX_CL_IMPORT_10(false, PFNCLENQUEUEREADBUFFERPROC, clEnqueueReadBuffer); \ + BX_CL_IMPORT_10(false, PFNCLENQUEUEWRITEBUFFERPROC, clEnqueueWriteBuffer); \ + BX_CL_IMPORT_10(false, PFNCLENQUEUECOPYBUFFERPROC, clEnqueueCopyBuffer); \ + BX_CL_IMPORT_10(false, PFNCLENQUEUEREADIMAGEPROC, clEnqueueReadImage); \ + BX_CL_IMPORT_10(false, PFNCLENQUEUEWRITEIMAGEPROC, clEnqueueWriteImage); \ + BX_CL_IMPORT_10(false, PFNCLENQUEUECOPYIMAGEPROC, clEnqueueCopyImage); \ + BX_CL_IMPORT_10(false, PFNCLENQUEUECOPYIMAGETOBUFFERPROC, clEnqueueCopyImageToBuffer); \ + BX_CL_IMPORT_10(false, PFNCLENQUEUEMAPBUFFERPROC, clEnqueueMapBuffer); \ + BX_CL_IMPORT_10(false, PFNCLENQUEUEMAPIMAGEPROC, clEnqueueMapImage); \ + BX_CL_IMPORT_10(false, PFNCLENQUEUEUNMAPMEMOBJECTPROC, clEnqueueUnmapMemObject); \ + BX_CL_IMPORT_10(false, PFNCLENQUEUENDRANGEKERNELPROC, clEnqueueNDRangeKernel); \ + BX_CL_IMPORT_10(false, PFNCLENQUEUETASKPROC, clEnqueueTask); \ + BX_CL_IMPORT_10(false, PFNCLENQUEUENATIVEKERNELPROC, clEnqueueNativeKernel); \ + \ + BX_CL_IMPORT_END + +#define BX_CL_IMPORT_ALL_11 \ + /* Memory Object APIs */ \ + BX_CL_IMPORT_11(false, PFNCLCREATEIMAGE2DPROC, clCreateImage2D); \ + BX_CL_IMPORT_11(false, PFNCLCREATEIMAGE3DPROC, clCreateImage3D); \ + BX_CL_IMPORT_11(false, PFNCLCREATESUBBUFFERPROC, clCreateSubBuffer); \ + BX_CL_IMPORT_11(false, PFNCLSETMEMOBJECTDESTRUCTORCALLBACKPROC, clSetMemObjectDestructorCallback); \ + /* Event Object APIs */ \ + BX_CL_IMPORT_11(false, PFNCLCREATEUSEREVENTPROC, clCreateUserEvent); \ + BX_CL_IMPORT_11(false, PFNCLSETUSEREVENTSTATUSPROC, clSetUserEventStatus); \ + BX_CL_IMPORT_11(false, PFNCLSETEVENTCALLBACKPROC, clSetEventCallback); \ + /* Enqueued Commands APIs */ \ + BX_CL_IMPORT_11(false, PFNCLENQUEUEREADBUFFERRECTPROC, clEnqueueReadBufferRect); \ + BX_CL_IMPORT_11(false, PFNCLENQUEUEWRITEBUFFERRECTPROC, clEnqueueWriteBufferRect); \ + BX_CL_IMPORT_11(false, PFNCLENQUEUECOPYBUFFERRECTPROC, clEnqueueCopyBufferRect); \ + \ + BX_CL_IMPORT_END + +#define BX_CL_IMPORT_ALL_12 \ + /* Device APIs */ \ + BX_CL_IMPORT_12(false, PFNCLCREATESUBDEVICESPROC, clCreateSubDevices); \ + BX_CL_IMPORT_12(false, PFNCLRETAINDEVICEPROC, clRetainDevice); \ + BX_CL_IMPORT_12(false, PFNCLRELEASEDEVICEPROC, clReleaseDevice); \ + BX_CL_IMPORT_12(false, PFNCLCREATEIMAGEPROC, clCreateImage); \ + /* Program Object APIs */ \ + BX_CL_IMPORT_12(false, PFNCLCREATEPROGRAMWITHBUILTINKERNELSPROC, clCreateProgramWithBuiltInKernels); \ + BX_CL_IMPORT_12(false, PFNCLCOMPILEPROGRAMPROC, clCompileProgram); \ + BX_CL_IMPORT_12(false, PFNCLLINKPROGRAMPROC, clLinkProgram); \ + BX_CL_IMPORT_12(false, PFNCLUNLOADPLATFORMCOMPILERPROC, clUnloadPlatformCompiler); \ + /* Kernel Object APIs */ \ + BX_CL_IMPORT_12(false, PFNCLGETKERNELARGINFOPROC, clGetKernelArgInfo); \ + /* Enqueued Commands APIs */ \ + BX_CL_IMPORT_12(false, PFNCLENQUEUEFILLBUFFERPROC, clEnqueueFillBuffer); \ + BX_CL_IMPORT_12(false, PFNCLENQUEUEFILLIMAGEPROC, clEnqueueFillImage); \ + BX_CL_IMPORT_12(false, PFNCLENQUEUEMIGRATEMEMOBJECTSPROC, clEnqueueMigrateMemObjects); \ + BX_CL_IMPORT_12(false, PFNCLENQUEUEMARKERWITHWAITLISTPROC, clEnqueueMarkerWithWaitList); \ + BX_CL_IMPORT_12(false, PFNCLENQUEUEBARRIERWITHWAITLISTPROC, clEnqueueBarrierWithWaitList); \ + \ + BX_CL_IMPORT_END + +#define BX_CL_IMPORT_ALL \ + BX_CL_IMPORT_ALL_10 \ + BX_CL_IMPORT_ALL_11 \ + BX_CL_IMPORT_ALL_12 \ + \ + BX_CL_IMPORT_END + +#define BX_CL_IMPORT_10(_optional, _proto, _func) BX_CL_IMPORT(10, _optional, _proto, _func) +#define BX_CL_IMPORT_11(_optional, _proto, _func) BX_CL_IMPORT(11, _optional, _proto, _func) +#define BX_CL_IMPORT_12(_optional, _proto, _func) BX_CL_IMPORT(12, _optional, _proto, _func) +#define BX_CL_IMPORT_END + +#define BX_CL_IMPORT(_version, _optional, _proto, _func) extern "C" _proto _func +BX_CL_IMPORT_ALL +#undef BX_CL_IMPORT + +#if defined(BX_CL_IMPLEMENTATION) +extern "C" +{ +#define BX_CL_IMPORT(_version, _optional, _proto, _func) _proto _func +BX_CL_IMPORT_ALL +#undef BX_CL_IMPORT +}; + +#include "os.h" + +namespace bx +{ + struct OpenCLContext + { + OpenCLContext() + : m_handle(NULL) + , m_refCount(0) + { + } + + int32_t load() + { + if (NULL != m_handle) + { + int32_t ref = ++m_refCount; + return ref; + } + + const char* filePath = +#if BX_PLATFORM_LINUX + "libOpenCL.so" +#elif BX_PLATFORM_OSX + "/Library/Frameworks/OpenCL.framework/OpenCL" +#elif BX_PLATFORM_WINDOWS + "opencl.dll" +#else + "??? unknown OpenCL platform ???" +#endif // BX_PLATFORM_ + ; + + m_handle = bx::dlopen(filePath); + if (NULL == m_handle) + { + BX_TRACE("Unable to find OpenCL '%s' dynamic library.", filePath); + return 0; + } + + m_refCount = 1; + +#define BX_CL_IMPORT(_version, _optional, _proto, _func) _func = (_proto)bx::dlsym(m_handle, #_func) + BX_CL_IMPORT_ALL +#undef BX_CL_IMPORT + + return 1; + } + + int32_t unload() + { + BX_CHECK(m_refCount > 0 && NULL != m_handle, "OpenCL is not loaded."); + + int32_t ref = --m_refCount; + if (0 == ref) + { + dlclose(m_handle); + m_handle = NULL; + } + + return ref; + } + + void* m_handle; + int32_t m_refCount; + }; + + static OpenCLContext s_ctx; + + int32_t clLoad() + { + return s_ctx.load(); + } + + int32_t clUnload() + { + return s_ctx.unload(); + } + +} // namespace bx + +#undef BX_CL_IMPORT_ALL +#undef BX_CL_IMPORT_ALL_10 +#undef BX_CL_IMPORT_ALL_11 +#undef BX_CL_IMPORT_ALL_12 +#undef BX_CL_IMPORT_END + +#endif // defined(BX_CL_IMPLEMENTATION) + +#endif // __OPENCL_CL_H + +#endif // BX_CL_H_HEADER_GUARD diff --git a/deps/include/bx/commandline.h b/deps/include/bx/commandline.h new file mode 100644 index 0000000..d366eff --- /dev/null +++ b/deps/include/bx/commandline.h @@ -0,0 +1,188 @@ +/* + * Copyright 2010-2015 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#ifndef BX_COMMANDLINE_H_HEADER_GUARD +#define BX_COMMANDLINE_H_HEADER_GUARD + +#include "bx.h" +#include "string.h" + +namespace bx +{ + class CommandLine + { + public: + CommandLine(int _argc, char const* const* _argv) + : m_argc(_argc) + , m_argv(_argv) + { + } + + const char* findOption(const char* _long, const char* _default) const + { + const char* result = find('\0', _long, 1); + return result == NULL ? _default : result; + } + + const char* findOption(const char _short, const char* _long, const char* _default) const + { + const char* result = find(_short, _long, 1); + return result == NULL ? _default : result; + } + + const char* findOption(const char* _long, int _numParams = 1) const + { + const char* result = find('\0', _long, _numParams); + return result; + } + + const char* findOption(const char _short, const char* _long = NULL, int _numParams = 1) const + { + const char* result = find(_short, _long, _numParams); + return result; + } + + bool hasArg(const char _short, const char* _long = NULL) const + { + const char* arg = findOption(_short, _long, 0); + return NULL != arg; + } + + bool hasArg(const char* _long) const + { + const char* arg = findOption('\0', _long, 0); + return NULL != arg; + } + + bool hasArg(const char*& _value, const char _short, const char* _long = NULL) const + { + const char* arg = findOption(_short, _long, 1); + _value = arg; + return NULL != arg; + } + + bool hasArg(int& _value, const char _short, const char* _long = NULL) const + { + const char* arg = findOption(_short, _long, 1); + if (NULL != arg) + { + _value = atoi(arg); + return true; + } + + return false; + } + + bool hasArg(unsigned int& _value, const char _short, const char* _long = NULL) const + { + const char* arg = findOption(_short, _long, 1); + if (NULL != arg) + { + _value = atoi(arg); + return true; + } + + return false; + } + + bool hasArg(float& _value, const char _short, const char* _long = NULL) const + { + const char* arg = findOption(_short, _long, 1); + if (NULL != arg) + { + _value = float(atof(arg)); + return true; + } + + return false; + } + + bool hasArg(double& _value, const char _short, const char* _long = NULL) const + { + const char* arg = findOption(_short, _long, 1); + if (NULL != arg) + { + _value = atof(arg); + return true; + } + + return false; + } + + bool hasArg(bool& _value, const char _short, const char* _long = NULL) const + { + const char* arg = findOption(_short, _long, 1); + if (NULL != arg) + { + if ('0' == *arg || (0 == stricmp(arg, "false") ) ) + { + _value = false; + } + else if ('0' != *arg || (0 == stricmp(arg, "true") ) ) + { + _value = true; + } + + return true; + } + + return false; + } + + private: + const char* find(const char _short, const char* _long, int _numParams) const + { + for (int ii = 0; ii < m_argc; ++ii) + { + const char* arg = m_argv[ii]; + if ('-' == *arg) + { + ++arg; + if (_short == *arg) + { + if (1 == strlen(arg) ) + { + if (0 == _numParams) + { + return ""; + } + else if (ii+_numParams < m_argc + && '-' != *m_argv[ii+1] ) + { + return m_argv[ii+1]; + } + + return NULL; + } + } + else if (NULL != _long + && '-' == *arg + && 0 == stricmp(arg+1, _long) ) + { + if (0 == _numParams) + { + return ""; + } + else if (ii+_numParams < m_argc + && '-' != *m_argv[ii+1] ) + { + return m_argv[ii+1]; + } + + return NULL; + } + } + } + + return NULL; + } + + int m_argc; + char const* const* m_argv; + }; + +} // namespace bx + +#endif /// BX_COMMANDLINE_H_HEADER_GUARD diff --git a/deps/include/bx/config.h b/deps/include/bx/config.h new file mode 100644 index 0000000..9a439f9 --- /dev/null +++ b/deps/include/bx/config.h @@ -0,0 +1,46 @@ +/* + * Copyright 2010-2015 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#ifndef BX_CONFIG_H_HEADER_GUARD +#define BX_CONFIG_H_HEADER_GUARD + +#include "platform.h" + +#ifndef BX_CONFIG_ALLOCATOR_DEBUG +# define BX_CONFIG_ALLOCATOR_DEBUG 0 +#endif // BX_CONFIG_DEBUG_ALLOC + +#ifndef BX_CONFIG_ALLOCATOR_CRT +# define BX_CONFIG_ALLOCATOR_CRT 1 +#endif // BX_CONFIG_ALLOCATOR_CRT + +#ifndef BX_CONFIG_SPSCQUEUE_USE_MUTEX +# define BX_CONFIG_SPSCQUEUE_USE_MUTEX 0 +#endif // BX_CONFIG_SPSCQUEUE_USE_MUTEX + +#ifndef BX_CONFIG_CRT_FILE_READER_WRITER +# define BX_CONFIG_CRT_FILE_READER_WRITER (0 \ + || BX_PLATFORM_ANDROID \ + || BX_PLATFORM_FREEBSD \ + || BX_PLATFORM_EMSCRIPTEN \ + || BX_PLATFORM_IOS \ + || BX_PLATFORM_LINUX \ + || BX_PLATFORM_OSX \ + || BX_PLATFORM_QNX \ + || BX_PLATFORM_RPI \ + || BX_PLATFORM_WINDOWS \ + || BX_PLATFORM_WINRT \ + ? 1 : 0) +#endif // BX_CONFIG_CRT_FILE_READER_WRITER + +#ifndef BX_CONFIG_SEMAPHORE_PTHREAD +# define BX_CONFIG_SEMAPHORE_PTHREAD (BX_PLATFORM_OSX || BX_PLATFORM_IOS) +#endif // BX_CONFIG_SEMAPHORE_PTHREAD + +#ifndef BX_CONFIG_SUPPORTS_THREADING +# define BX_CONFIG_SUPPORTS_THREADING !(BX_PLATFORM_EMSCRIPTEN) +#endif // BX_CONFIG_SUPPORTS_THREADING + +#endif // BX_CONFIG_H_HEADER_GUARD diff --git a/deps/include/bx/cpu.h b/deps/include/bx/cpu.h new file mode 100644 index 0000000..a9cab51 --- /dev/null +++ b/deps/include/bx/cpu.h @@ -0,0 +1,152 @@ +/* + * Copyright 2010-2015 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#ifndef BX_CPU_H_HEADER_GUARD +#define BX_CPU_H_HEADER_GUARD + +#include "bx.h" + +#if BX_COMPILER_MSVC +# if BX_PLATFORM_XBOX360 +# include +# include +# else +# include // math.h is included because VS bitches: + // warning C4985: 'ceil': attributes not present on previous declaration. + // must be included before intrin.h. +# include +# include +# endif // !BX_PLATFORM_XBOX360 +extern "C" void _ReadBarrier(); +extern "C" void _WriteBarrier(); +extern "C" void _ReadWriteBarrier(); +# pragma intrinsic(_ReadBarrier) +# pragma intrinsic(_WriteBarrier) +# pragma intrinsic(_ReadWriteBarrier) +# pragma intrinsic(_InterlockedIncrement) +# pragma intrinsic(_InterlockedDecrement) +# pragma intrinsic(_InterlockedCompareExchange) +#endif // BX_COMPILER_MSVC + +namespace bx +{ + /// + inline void readBarrier() + { +#if BX_COMPILER_MSVC + _ReadBarrier(); +#else + asm volatile("":::"memory"); +#endif // BX_COMPILER + } + + /// + inline void writeBarrier() + { +#if BX_COMPILER_MSVC + _WriteBarrier(); +#else + asm volatile("":::"memory"); +#endif // BX_COMPILER + } + + /// + inline void readWriteBarrier() + { +#if BX_COMPILER_MSVC + _ReadWriteBarrier(); +#else + asm volatile("":::"memory"); +#endif // BX_COMPILER + } + + /// + inline void memoryBarrier() + { +#if BX_PLATFORM_XBOX360 + __lwsync(); +#elif BX_PLATFORM_WINRT + MemoryBarrier(); +#elif BX_COMPILER_MSVC + _mm_mfence(); +#else + __sync_synchronize(); +// asm volatile("mfence":::"memory"); +#endif // BX_COMPILER + } + + /// Returns the resulting incremented value. + inline int32_t atomicInc(volatile void* _ptr) + { +#if BX_COMPILER_MSVC + return _InterlockedIncrement( (volatile LONG*)(_ptr) ); +#else + return __sync_add_and_fetch( (volatile int32_t*)_ptr, 1); +#endif // BX_COMPILER + } + + /// Returns the resulting decremented value. + inline int32_t atomicDec(volatile void* _ptr) + { +#if BX_COMPILER_MSVC + return _InterlockedDecrement( (volatile LONG*)(_ptr) ); +#else + return __sync_sub_and_fetch( (volatile int32_t*)_ptr, 1); +#endif // BX_COMPILER + } + + /// + inline int32_t atomicCompareAndSwap(volatile void* _ptr, int32_t _old, int32_t _new) + { +#if BX_COMPILER_MSVC + return _InterlockedCompareExchange( (volatile LONG*)(_ptr), _new, _old); +#else + return __sync_val_compare_and_swap( (volatile int32_t*)_ptr, _old, _new); +#endif // BX_COMPILER + } + + /// + inline void* atomicExchangePtr(void** _ptr, void* _new) + { +#if BX_COMPILER_MSVC + return InterlockedExchangePointer(_ptr, _new); /* VS2012 no intrinsics */ +#else + return __sync_lock_test_and_set(_ptr, _new); +#endif // BX_COMPILER + } + + /// + inline int32_t atomicTestAndInc(volatile void* _ptr, int32_t _test) + { + int32_t oldVal; + int32_t newVal = *(int32_t volatile*)_ptr; + do + { + oldVal = newVal; + newVal = atomicCompareAndSwap(_ptr, oldVal, newVal >= _test ? _test : newVal+1); + + } while (oldVal != newVal); + + return oldVal; + } + + /// + inline int32_t atomicTestAndDec(volatile void* _ptr, int32_t _test) + { + int32_t oldVal; + int32_t newVal = *(int32_t volatile*)_ptr; + do + { + oldVal = newVal; + newVal = atomicCompareAndSwap(_ptr, oldVal, newVal <= _test ? _test : newVal-1); + + } while (oldVal != newVal); + + return oldVal; + } + +} // namespace bx + +#endif // BX_CPU_H_HEADER_GUARD diff --git a/deps/include/bx/debug.h b/deps/include/bx/debug.h new file mode 100644 index 0000000..7aff6b1 --- /dev/null +++ b/deps/include/bx/debug.h @@ -0,0 +1,73 @@ +/* + * Copyright 2010-2015 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#ifndef BX_DEBUG_H_HEADER_GUARD +#define BX_DEBUG_H_HEADER_GUARD + +#include "bx.h" + +#if BX_PLATFORM_ANDROID +# include +#elif BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT || BX_PLATFORM_XBOX360 +extern "C" __declspec(dllimport) void __stdcall OutputDebugStringA(const char* _str); +#elif BX_PLATFORM_IOS || BX_PLATFORM_OSX +# if defined(__OBJC__) +# import +# else +# include +extern "C" void NSLog(CFStringRef _format, ...); +# endif // defined(__OBJC__) +#elif 0 // BX_PLATFORM_EMSCRIPTEN +# include +#else +# include +#endif // BX_PLATFORM_WINDOWS + +namespace bx +{ +#if BX_COMPILER_CLANG_ANALYZER + inline __attribute__((analyzer_noreturn)) void debugBreak(); +#endif // BX_COMPILER_CLANG_ANALYZER + + inline void debugBreak() + { +#if BX_COMPILER_MSVC + __debugbreak(); +#elif BX_CPU_ARM + __builtin_trap(); +// asm("bkpt 0"); +#elif !BX_PLATFORM_NACL && BX_CPU_X86 && (BX_COMPILER_GCC || BX_COMPILER_CLANG) + // NaCl doesn't like int 3: + // NativeClient: NaCl module load failed: Validation failure. File violates Native Client safety rules. + __asm__ ("int $3"); +#else // cross platform implementation + int* int3 = (int*)3L; + *int3 = 3; +#endif // BX + } + + inline void debugOutput(const char* _out) + { +#if BX_PLATFORM_ANDROID + __android_log_write(ANDROID_LOG_DEBUG, "", _out); +#elif BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT || BX_PLATFORM_XBOX360 + OutputDebugStringA(_out); +#elif BX_PLATFORM_IOS || BX_PLATFORM_OSX +# if defined(__OBJC__) + NSLog(@"%s", _out); +# else + NSLog(__CFStringMakeConstantString("%s"), _out); +# endif // defined(__OBJC__) +#elif 0 // BX_PLATFORM_EMSCRIPTEN + emscripten_log(EM_LOG_CONSOLE, "%s", _out); +#else + fputs(_out, stdout); + fflush(stdout); +#endif // BX_PLATFORM_ + } + +} // namespace bx + +#endif // BX_DEBUG_H_HEADER_GUARD diff --git a/deps/include/bx/endian.h b/deps/include/bx/endian.h new file mode 100644 index 0000000..b8df391 --- /dev/null +++ b/deps/include/bx/endian.h @@ -0,0 +1,87 @@ +/* + * Copyright 2010-2015 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#ifndef BX_ENDIAN_H_HEADER_GUARD +#define BX_ENDIAN_H_HEADER_GUARD + +#include "bx.h" + +namespace bx +{ + inline uint16_t endianSwap(uint16_t _in) + { + return (_in>>8) | (_in<<8); + } + + inline uint32_t endianSwap(uint32_t _in) + { + return (_in>>24) | (_in<<24) + | ( (_in&0x00ff0000)>>8) | ( (_in&0x0000ff00)<<8) + ; + } + + inline uint64_t endianSwap(uint64_t _in) + { + return (_in>>56) | (_in<<56) + | ( (_in&UINT64_C(0x00ff000000000000) )>>40) | ( (_in&UINT64_C(0x000000000000ff00) )<<40) + | ( (_in&UINT64_C(0x0000ff0000000000) )>>24) | ( (_in&UINT64_C(0x0000000000ff0000) )<<24) + | ( (_in&UINT64_C(0x000000ff00000000) )>>8) | ( (_in&UINT64_C(0x00000000ff000000) )<<8) + ; + } + + inline int16_t endianSwap(int16_t _in) + { + return (int16_t)endianSwap( (uint16_t)_in); + } + + inline int32_t endianSwap(int32_t _in) + { + return (int32_t)endianSwap( (uint32_t)_in); + } + + inline int64_t endianSwap(int64_t _in) + { + return (int64_t)endianSwap( (uint64_t)_in); + } + + /// Input argument is encoded as little endian, convert it if neccessary + /// depending on host CPU endianess. + template + inline Ty toLittleEndian(const Ty _in) + { +#if BX_CPU_ENDIAN_BIG + return endianSwap(_in); +#else + return _in; +#endif // BX_CPU_ENDIAN_BIG + } + + /// Input argument is encoded as big endian, convert it if neccessary + /// depending on host CPU endianess. + template + inline Ty toBigEndian(const Ty _in) + { +#if BX_CPU_ENDIAN_LITTLE + return endianSwap(_in); +#else + return _in; +#endif // BX_CPU_ENDIAN_LITTLE + } + + /// If _littleEndian is true, converts input argument to from little endian + /// to host CPU endiness. + template + inline Ty toHostEndian(const Ty _in, bool _fromLittleEndian) + { +#if BX_CPU_ENDIAN_LITTLE + return _fromLittleEndian ? _in : endianSwap(_in); +#else + return _fromLittleEndian ? endianSwap(_in) : _in; +#endif // BX_CPU_ENDIAN_LITTLE + } + +} // namespace bx + +#endif // BX_ENDIAN_H_HEADER_GUARD diff --git a/deps/include/bx/float4_langext.h b/deps/include/bx/float4_langext.h new file mode 100644 index 0000000..8a6c6cd --- /dev/null +++ b/deps/include/bx/float4_langext.h @@ -0,0 +1,482 @@ +/* + * Copyright 2010-2015 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#ifndef BX_FLOAT4_LANGEXT_H_HEADER_GUARD +#define BX_FLOAT4_LANGEXT_H_HEADER_GUARD + +#include + +namespace bx +{ + typedef union float4_t + { + float __attribute__((vector_size(16))) vf; + int32_t __attribute__((vector_size(16))) vi; + uint32_t __attribute__((vector_size(16))) vu; + float fxyzw[4]; + int32_t ixyzw[4]; + uint32_t uxyzw[4]; + + } float4_t; + +#define ELEMx 0 +#define ELEMy 1 +#define ELEMz 2 +#define ELEMw 3 +#define IMPLEMENT_SWIZZLE(_x, _y, _z, _w) \ + BX_FLOAT4_FORCE_INLINE float4_t float4_swiz_##_x##_y##_z##_w(float4_t _a) \ + { \ + float4_t result; \ + result.vf = __builtin_shufflevector(_a.vf, _a.vf, ELEM##_x, ELEM##_y, ELEM##_z, ELEM##_w); \ + return result; \ + } + +#include "float4_swizzle.inl" + +#undef IMPLEMENT_SWIZZLE +#undef ELEMw +#undef ELEMz +#undef ELEMy +#undef ELEMx + +#define IMPLEMENT_TEST(_xyzw, _mask) \ + BX_FLOAT4_FORCE_INLINE bool float4_test_any_##_xyzw(float4_t _test) \ + { \ + uint32_t tmp = ( (_test.uxyzw[3]>>31)<<3) \ + | ( (_test.uxyzw[2]>>31)<<2) \ + | ( (_test.uxyzw[1]>>31)<<1) \ + | ( _test.uxyzw[0]>>31) \ + ; \ + return 0 != (tmp&(_mask) ); \ + } \ + \ + BX_FLOAT4_FORCE_INLINE bool float4_test_all_##_xyzw(float4_t _test) \ + { \ + uint32_t tmp = ( (_test.uxyzw[3]>>31)<<3) \ + | ( (_test.uxyzw[2]>>31)<<2) \ + | ( (_test.uxyzw[1]>>31)<<1) \ + | ( _test.uxyzw[0]>>31) \ + ; \ + return (_mask) == (tmp&(_mask) ); \ + } + +IMPLEMENT_TEST(x , 0x1); +IMPLEMENT_TEST(y , 0x2); +IMPLEMENT_TEST(xy , 0x3); +IMPLEMENT_TEST(z , 0x4); +IMPLEMENT_TEST(xz , 0x5); +IMPLEMENT_TEST(yz , 0x6); +IMPLEMENT_TEST(xyz , 0x7); +IMPLEMENT_TEST(w , 0x8); +IMPLEMENT_TEST(xw , 0x9); +IMPLEMENT_TEST(yw , 0xa); +IMPLEMENT_TEST(xyw , 0xb); +IMPLEMENT_TEST(zw , 0xc); +IMPLEMENT_TEST(xzw , 0xd); +IMPLEMENT_TEST(yzw , 0xe); +IMPLEMENT_TEST(xyzw , 0xf); + +#undef IMPLEMENT_TEST + + BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_xyAB(float4_t _a, float4_t _b) + { + float4_t result; + result.vf = __builtin_shufflevector(_a.vf, _b.vf, 0, 1, 4, 5); + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_ABxy(float4_t _a, float4_t _b) + { + float4_t result; + result.vf = __builtin_shufflevector(_a.vf, _b.vf, 4, 5, 0, 1); + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_CDzw(float4_t _a, float4_t _b) + { + float4_t result; + result.vf = __builtin_shufflevector(_a.vf, _b.vf, 5, 7, 2, 3); + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_zwCD(float4_t _a, float4_t _b) + { + float4_t result; + result.vf = __builtin_shufflevector(_a.vf, _b.vf, 2, 3, 5, 7); + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_xAyB(float4_t _a, float4_t _b) + { + float4_t result; + result.vf = __builtin_shufflevector(_a.vf, _b.vf, 0, 4, 1, 5); + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_yBxA(float4_t _a, float4_t _b) + { + float4_t result; + result.vf = __builtin_shufflevector(_a.vf, _b.vf, 1, 5, 0, 4); + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_zCwD(float4_t _a, float4_t _b) + { + float4_t result; + result.vf = __builtin_shufflevector(_a.vf, _b.vf, 2, 6, 3, 7); + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_CzDw(float4_t _a, float4_t _b) + { + float4_t result; + result.vf = __builtin_shufflevector(_a.vf, _b.vf, 6, 2, 7, 3); + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_xAzC(float4_t _a, float4_t _b) + { + float4_t result; + result.vf = __builtin_shufflevector(_a.vf, _b.vf, 0, 4, 2, 6); + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_yBwD(float4_t _a, float4_t _b) + { + float4_t result; + result.vf = __builtin_shufflevector(_a.vf, _b.vf, 1, 5, 3, 7); + return result; + } + + BX_FLOAT4_FORCE_INLINE float float4_x(float4_t _a) + { + return _a.fxyzw[0]; + } + + BX_FLOAT4_FORCE_INLINE float float4_y(float4_t _a) + { + return _a.fxyzw[1]; + } + + BX_FLOAT4_FORCE_INLINE float float4_z(float4_t _a) + { + return _a.fxyzw[2]; + } + + BX_FLOAT4_FORCE_INLINE float float4_w(float4_t _a) + { + return _a.fxyzw[3]; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_ld(const void* _ptr) + { + const uint32_t* input = reinterpret_cast(_ptr); + float4_t result; + result.uxyzw[0] = input[0]; + result.uxyzw[1] = input[1]; + result.uxyzw[2] = input[2]; + result.uxyzw[3] = input[3]; + return result; + } + + BX_FLOAT4_FORCE_INLINE void float4_st(void* _ptr, float4_t _a) + { + uint32_t* result = reinterpret_cast(_ptr); + result[0] = _a.uxyzw[0]; + result[1] = _a.uxyzw[1]; + result[2] = _a.uxyzw[2]; + result[3] = _a.uxyzw[3]; + } + + BX_FLOAT4_FORCE_INLINE void float4_stx(void* _ptr, float4_t _a) + { + uint32_t* result = reinterpret_cast(_ptr); + result[0] = _a.uxyzw[0]; + } + + BX_FLOAT4_FORCE_INLINE void float4_stream(void* _ptr, float4_t _a) + { + uint32_t* result = reinterpret_cast(_ptr); + result[0] = _a.uxyzw[0]; + result[1] = _a.uxyzw[1]; + result[2] = _a.uxyzw[2]; + result[3] = _a.uxyzw[3]; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_ld(float _x, float _y, float _z, float _w) + { + float4_t result; + result.vf = { _x, _y, _z, _w }; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_ild(uint32_t _x, uint32_t _y, uint32_t _z, uint32_t _w) + { + float4_t result; + result.vu = { _x, _y, _z, _w }; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_splat(const void* _ptr) + { + const uint32_t val = *reinterpret_cast(_ptr); + float4_t result; + result.vu = { val, val, val, val }; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_splat(float _a) + { + return float4_ld(_a, _a, _a, _a); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_isplat(uint32_t _a) + { + return float4_ild(_a, _a, _a, _a); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_zero() + { + return float4_ild(0, 0, 0, 0); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_itof(float4_t _a) + { + float4_t result; + result.vf = __builtin_convertvector(_a.vi, float __attribute__((vector_size(16))) ); + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_ftoi(float4_t _a) + { + float4_t result; + result.vi = __builtin_convertvector(_a.vf, int32_t __attribute__((vector_size(16))) ); + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_round(float4_t _a) + { + const float4_t tmp = float4_ftoi(_a); + const float4_t result = float4_itof(tmp); + + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_add(float4_t _a, float4_t _b) + { + float4_t result; + result.vf = _a.vf + _b.vf; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_sub(float4_t _a, float4_t _b) + { + float4_t result; + result.vf = _a.vf - _b.vf; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_mul(float4_t _a, float4_t _b) + { + float4_t result; + result.vf = _a.vf * _b.vf; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_div(float4_t _a, float4_t _b) + { + float4_t result; + result.vf = _a.vf / _b.vf; + return result; + } + +#if 0 + BX_FLOAT4_FORCE_INLINE float4_t float4_rcp_est(float4_t _a) + { + float4_t result; + const float4_t one = float4_splat(1.0f); + result.vf = one / _a.vf; + return result; + } +#endif // 0 + + BX_FLOAT4_FORCE_INLINE float4_t float4_sqrt(float4_t _a) + { + float4_t result; + result.vf[0] = sqrtf(_a.vf[0]); + result.vf[1] = sqrtf(_a.vf[1]); + result.vf[2] = sqrtf(_a.vf[2]); + result.vf[3] = sqrtf(_a.vf[3]); + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_rsqrt_est(float4_t _a) + { + float4_t result; + result.vf[0] = 1.0f / sqrtf(_a.vf[0]); + result.vf[1] = 1.0f / sqrtf(_a.vf[1]); + result.vf[2] = 1.0f / sqrtf(_a.vf[2]); + result.vf[3] = 1.0f / sqrtf(_a.vf[3]); + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_cmpeq(float4_t _a, float4_t _b) + { + float4_t result; + result.vi = _a.vf == _b.vf; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_cmplt(float4_t _a, float4_t _b) + { + float4_t result; + result.vi = _a.vf < _b.vf; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_cmple(float4_t _a, float4_t _b) + { + float4_t result; + result.vi = _a.vf <= _b.vf; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_cmpgt(float4_t _a, float4_t _b) + { + float4_t result; + result.vi = _a.vf > _b.vf; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_cmpge(float4_t _a, float4_t _b) + { + float4_t result; + result.vi = _a.vf >= _b.vf; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_and(float4_t _a, float4_t _b) + { + float4_t result; + result.vu = _a.vu & _b.vu; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_andc(float4_t _a, float4_t _b) + { + float4_t result; + result.vu = _a.vu & ~_b.vu; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_or(float4_t _a, float4_t _b) + { + float4_t result; + result.vu = _a.vu | _b.vu; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_xor(float4_t _a, float4_t _b) + { + float4_t result; + result.vu = _a.vu ^ _b.vu; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_sll(float4_t _a, int _count) + { + float4_t result; + const float4_t count = float4_isplat(_count); + result.vu = _a.vu << count.vi; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_srl(float4_t _a, int _count) + { + float4_t result; + const float4_t count = float4_isplat(_count); + result.vu = _a.vu >> count.vi; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_sra(float4_t _a, int _count) + { + float4_t result; + const float4_t count = float4_isplat(_count); + result.vi = _a.vi >> count.vi; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_icmpeq(float4_t _a, float4_t _b) + { + float4_t result; + result.vi = _a.vi == _b.vi; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_icmplt(float4_t _a, float4_t _b) + { + float4_t result; + result.vi = _a.vi < _b.vi; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_icmpgt(float4_t _a, float4_t _b) + { + float4_t result; + result.vi = _a.vi > _b.vi; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_iadd(float4_t _a, float4_t _b) + { + float4_t result; + result.vi = _a.vi + _b.vi; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_isub(float4_t _a, float4_t _b) + { + float4_t result; + result.vi = _a.vi - _b.vi; + return result; + } + +} // namespace bx + +#define float4_rcp float4_rcp_ni +#define float4_orx float4_orx_ni +#define float4_orc float4_orc_ni +#define float4_neg float4_neg_ni +#define float4_madd float4_madd_ni +#define float4_nmsub float4_nmsub_ni +#define float4_div_nr float4_div_nr_ni +#define float4_selb float4_selb_ni +#define float4_sels float4_sels_ni +#define float4_not float4_not_ni +#define float4_abs float4_abs_ni +#define float4_clamp float4_clamp_ni +#define float4_lerp float4_lerp_ni +#define float4_rcp_est float4_rcp_ni +#define float4_rsqrt float4_rsqrt_ni +#define float4_rsqrt_nr float4_rsqrt_nr_ni +#define float4_rsqrt_carmack float4_rsqrt_carmack_ni +#define float4_sqrt_nr float4_sqrt_nr_ni +#define float4_log2 float4_log2_ni +#define float4_exp2 float4_exp2_ni +#define float4_pow float4_pow_ni +#define float4_cross3 float4_cross3_ni +#define float4_normalize3 float4_normalize3_ni +#define float4_dot3 float4_dot3_ni +#define float4_dot float4_dot_ni +#define float4_ceil float4_ceil_ni +#define float4_floor float4_floor_ni +#define float4_min float4_min_ni +#define float4_max float4_max_ni +#define float4_imin float4_imin_ni +#define float4_imax float4_imax_ni +#include "float4_ni.h" + +#endif // BX_FLOAT4_LANGEXT_H_HEADER_GUARD diff --git a/deps/include/bx/float4_neon.h b/deps/include/bx/float4_neon.h new file mode 100644 index 0000000..b00c9c9 --- /dev/null +++ b/deps/include/bx/float4_neon.h @@ -0,0 +1,525 @@ +/* + * Copyright 2010-2015 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#ifndef BX_FLOAT4_NEON_H_HEADER_GUARD +#define BX_FLOAT4_NEON_H_HEADER_GUARD + +namespace bx +{ + typedef __builtin_neon_sf float4_t __attribute__( (__vector_size__(16) ) ); + + typedef __builtin_neon_sf _f32x2_t __attribute__( (__vector_size__( 8) ) ); + typedef __builtin_neon_si _i32x4_t __attribute__( (__vector_size__(16) ) ); + typedef __builtin_neon_usi _u32x4_t __attribute__( (__vector_size__(16) ) ); + +#define ELEMx 0 +#define ELEMy 1 +#define ELEMz 2 +#define ELEMw 3 +#define IMPLEMENT_SWIZZLE(_x, _y, _z, _w) \ + BX_FLOAT4_FORCE_INLINE float4_t float4_swiz_##_x##_y##_z##_w(float4_t _a) \ + { \ + return __builtin_shuffle(_a, (_u32x4_t){ ELEM##_x, ELEM##_y, ELEM##_z, ELEM##_w }); \ + } + +#include "float4_swizzle.inl" + +#undef IMPLEMENT_SWIZZLE +#undef ELEMw +#undef ELEMz +#undef ELEMy +#undef ELEMx + +#define IMPLEMENT_TEST(_xyzw, _swizzle) \ + BX_FLOAT4_FORCE_INLINE bool float4_test_any_##_xyzw(float4_t _test); \ + BX_FLOAT4_FORCE_INLINE bool float4_test_all_##_xyzw(float4_t _test); + +IMPLEMENT_TEST(x , xxxx); +IMPLEMENT_TEST(y , yyyy); +IMPLEMENT_TEST(xy , xyyy); +IMPLEMENT_TEST(z , zzzz); +IMPLEMENT_TEST(xz , xzzz); +IMPLEMENT_TEST(yz , yzzz); +IMPLEMENT_TEST(xyz , xyzz); +IMPLEMENT_TEST(w , wwww); +IMPLEMENT_TEST(xw , xwww); +IMPLEMENT_TEST(yw , ywww); +IMPLEMENT_TEST(xyw , xyww); +IMPLEMENT_TEST(zw , zwww); +IMPLEMENT_TEST(xzw , xzww); +IMPLEMENT_TEST(yzw , yzww); +IMPLEMENT_TEST(xyzw , xyzw); + +#undef IMPLEMENT_TEST + + BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_xyAB(float4_t _a, float4_t _b) + { + return __builtin_shuffle(_a, _b, (_u32x4_t){ 0, 1, 4, 5 }); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_ABxy(float4_t _a, float4_t _b) + { + return __builtin_shuffle(_a, _b, (_u32x4_t){ 4, 5, 0, 1 }); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_CDzw(float4_t _a, float4_t _b) + { + return __builtin_shuffle(_a, _b, (_u32x4_t){ 6, 7, 2, 3 }); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_zwCD(float4_t _a, float4_t _b) + { + return __builtin_shuffle(_a, _b, (_u32x4_t){ 2, 3, 6, 7 }); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_xAyB(float4_t _a, float4_t _b) + { + return __builtin_shuffle(_a, _b, (_u32x4_t){ 0, 4, 1, 5 }); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_yBxA(float4_t _a, float4_t _b) + { + return __builtin_shuffle(_a, _b, (_u32x4_t){ 1, 5, 0, 4 }); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_zCwD(float4_t _a, float4_t _b) + { + return __builtin_shuffle(_a, _b, (_u32x4_t){ 2, 6, 3, 7 }); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_CzDw(float4_t _a, float4_t _b) + { + return __builtin_shuffle(_a, _b, (_u32x4_t){ 6, 2, 7, 3 }); + } + + BX_FLOAT4_FORCE_INLINE float float4_x(float4_t _a) + { + return __builtin_neon_vget_lanev4sf(_a, 0, 3); + } + + BX_FLOAT4_FORCE_INLINE float float4_y(float4_t _a) + { + return __builtin_neon_vget_lanev4sf(_a, 1, 3); + } + + BX_FLOAT4_FORCE_INLINE float float4_z(float4_t _a) + { + return __builtin_neon_vget_lanev4sf(_a, 2, 3); + } + + BX_FLOAT4_FORCE_INLINE float float4_w(float4_t _a) + { + return __builtin_neon_vget_lanev4sf(_a, 3, 3); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_ld(const void* _ptr) + { + return __builtin_neon_vld1v4sf( (const __builtin_neon_sf*)_ptr); + } + + BX_FLOAT4_FORCE_INLINE void float4_st(void* _ptr, float4_t _a) + { + __builtin_neon_vst1v4sf( (__builtin_neon_sf*)_ptr, _a); + } + + BX_FLOAT4_FORCE_INLINE void float4_stx(void* _ptr, float4_t _a) + { + __builtin_neon_vst1_lanev4sf( (__builtin_neon_sf*)_ptr, _a, 0); + } + + BX_FLOAT4_FORCE_INLINE void float4_stream(void* _ptr, float4_t _a) + { + __builtin_neon_vst1v4sf( (__builtin_neon_sf*)_ptr, _a); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_ld(float _x, float _y, float _z, float _w) + { + const float4_t val[4] = {_x, _y, _z, _w}; + return float4_ld(val); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_ild(uint32_t _x, uint32_t _y, uint32_t _z, uint32_t _w) + { + const uint32_t val[4] = {_x, _y, _z, _w}; + const _i32x4_t tmp = __builtin_neon_vld1v4si( (const __builtin_neon_si*)val); + const float4_t result = __builtin_neon_vreinterpretv4sfv4si(tmp); + + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_splat(const void* _ptr) + { + const float4_t tmp0 = __builtin_neon_vld1v4sf( (const __builtin_neon_sf *)_ptr); + const _f32x2_t tmp1 = __builtin_neon_vget_lowv4sf(tmp0); + const float4_t result = __builtin_neon_vdup_lanev4sf(tmp1, 0); + + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_splat(float _a) + { + return __builtin_neon_vdup_nv4sf(_a); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_isplat(uint32_t _a) + { + const _i32x4_t tmp = __builtin_neon_vdup_nv4si( (__builtin_neon_si)_a); + const float4_t result = __builtin_neon_vreinterpretv4sfv4si(tmp); + + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_zero() + { + return float4_isplat(0); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_itof(float4_t _a) + { + const _i32x4_t itof = __builtin_neon_vreinterpretv4siv4sf(_a); + const float4_t result = __builtin_neon_vcvtv4si(itof, 1); + + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_ftoi(float4_t _a) + { + const _i32x4_t ftoi = __builtin_neon_vcvtv4sf(_a, 1); + const float4_t result = __builtin_neon_vreinterpretv4sfv4si(ftoi); + + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_add(float4_t _a, float4_t _b) + { + return __builtin_neon_vaddv4sf(_a, _b, 3); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_sub(float4_t _a, float4_t _b) + { + return __builtin_neon_vsubv4sf(_a, _b, 3); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_mul(float4_t _a, float4_t _b) + { + return __builtin_neon_vmulv4sf(_a, _b, 3); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_rcp_est(float4_t _a) + { + return __builtin_neon_vrecpev4sf(_a, 3); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_rsqrt_est(float4_t _a) + { + return __builtin_neon_vrsqrtev4sf(_a, 3); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_cmpeq(float4_t _a, float4_t _b) + { + const _i32x4_t tmp = __builtin_neon_vceqv4sf(_a, _b, 3); + const float4_t result = __builtin_neon_vreinterpretv4sfv4si(tmp); + + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_cmplt(float4_t _a, float4_t _b) + { + const _i32x4_t tmp = __builtin_neon_vcgtv4sf(_b, _a, 3); + const float4_t result = __builtin_neon_vreinterpretv4sfv4si(tmp); + + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_cmple(float4_t _a, float4_t _b) + { + const _i32x4_t tmp = __builtin_neon_vcgev4sf(_b, _a, 3); + const float4_t result = __builtin_neon_vreinterpretv4sfv4si(tmp); + + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_cmpgt(float4_t _a, float4_t _b) + { + const _i32x4_t tmp = __builtin_neon_vcgtv4sf(_a, _b, 3); + const float4_t result = __builtin_neon_vreinterpretv4sfv4si(tmp); + + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_cmpge(float4_t _a, float4_t _b) + { + const _i32x4_t tmp = __builtin_neon_vcgev4sf(_a, _b, 3); + const float4_t result = __builtin_neon_vreinterpretv4sfv4si(tmp); + + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_min(float4_t _a, float4_t _b) + { + return __builtin_neon_vminv4sf(_a, _b, 3); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_max(float4_t _a, float4_t _b) + { + return __builtin_neon_vmaxv4sf(_a, _b, 3); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_and(float4_t _a, float4_t _b) + { + const _i32x4_t tmp0 = __builtin_neon_vreinterpretv4siv4sf(_a); + const _i32x4_t tmp1 = __builtin_neon_vreinterpretv4siv4sf(_b); + const _i32x4_t tmp2 = __builtin_neon_vandv4si(tmp0, tmp1, 0); + const float4_t result = __builtin_neon_vreinterpretv4sfv4si(tmp2); + + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_andc(float4_t _a, float4_t _b) + { + const _i32x4_t tmp0 = __builtin_neon_vreinterpretv4siv4sf(_a); + const _i32x4_t tmp1 = __builtin_neon_vreinterpretv4siv4sf(_b); + const _i32x4_t tmp2 = __builtin_neon_vbicv4si(tmp0, tmp1, 0); + const float4_t result = __builtin_neon_vreinterpretv4sfv4si(tmp2); + + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_or(float4_t _a, float4_t _b) + { + const _i32x4_t tmp0 = __builtin_neon_vreinterpretv4siv4sf(_a); + const _i32x4_t tmp1 = __builtin_neon_vreinterpretv4siv4sf(_b); + const _i32x4_t tmp2 = __builtin_neon_vorrv4si(tmp0, tmp1, 0); + const float4_t result = __builtin_neon_vreinterpretv4sfv4si(tmp2); + + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_xor(float4_t _a, float4_t _b) + { + const _i32x4_t tmp0 = __builtin_neon_vreinterpretv4siv4sf(_a); + const _i32x4_t tmp1 = __builtin_neon_vreinterpretv4siv4sf(_b); + const _i32x4_t tmp2 = __builtin_neon_veorv4si(tmp0, tmp1, 0); + const float4_t result = __builtin_neon_vreinterpretv4sfv4si(tmp2); + + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_sll(float4_t _a, int _count) + { + if (__builtin_constant_p(_count) ) + { + const _i32x4_t tmp0 = __builtin_neon_vreinterpretv4siv4sf(_a); + const _i32x4_t tmp1 = __builtin_neon_vshl_nv4si(tmp0, _count, 0); + const float4_t result = __builtin_neon_vreinterpretv4sfv4si(tmp1); + + return result; + } + + const _i32x4_t tmp0 = __builtin_neon_vreinterpretv4siv4sf(_a); + const _i32x4_t shift = __builtin_neon_vdup_nv4si( (__builtin_neon_si)_count); + const _i32x4_t tmp1 = __builtin_neon_vshlv4si(tmp0, shift, 1); + const float4_t result = __builtin_neon_vreinterpretv4sfv4si(tmp1); + + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_srl(float4_t _a, int _count) + { + if (__builtin_constant_p(_count) ) + { + const _i32x4_t tmp0 = __builtin_neon_vreinterpretv4siv4sf(_a); + const _i32x4_t tmp1 = __builtin_neon_vshr_nv4si(tmp0, _count, 0); + const float4_t result = __builtin_neon_vreinterpretv4sfv4si(tmp1); + + return result; + } + + const _i32x4_t tmp0 = __builtin_neon_vreinterpretv4siv4sf(_a); + const _i32x4_t shift = __builtin_neon_vdup_nv4si( (__builtin_neon_si)-_count); + const _i32x4_t tmp1 = __builtin_neon_vshlv4si(tmp0, shift, 1); + const float4_t result = __builtin_neon_vreinterpretv4sfv4si(tmp1); + + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_sra(float4_t _a, int _count) + { + if (__builtin_constant_p(_count) ) + { + const _i32x4_t tmp0 = __builtin_neon_vreinterpretv4siv4sf(_a); + const _i32x4_t tmp1 = __builtin_neon_vshr_nv4si(tmp0, _count, 1); + const float4_t result = __builtin_neon_vreinterpretv4sfv4si(tmp1); + + return result; + } + + const _i32x4_t tmp0 = __builtin_neon_vreinterpretv4siv4sf(_a); + const _i32x4_t shift = __builtin_neon_vdup_nv4si( (__builtin_neon_si)-_count); + const _i32x4_t tmp1 = __builtin_neon_vshlv4si(tmp0, shift, 1); + const float4_t result = __builtin_neon_vreinterpretv4sfv4si(tmp1); + + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_madd(float4_t _a, float4_t _b, float4_t _c) + { + return __builtin_neon_vmlav4sf(_c, _a, _b, 3); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_nmsub(float4_t _a, float4_t _b, float4_t _c) + { + return __builtin_neon_vmlsv4sf(_c, _a, _b, 3); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_icmpeq(float4_t _a, float4_t _b) + { + const _i32x4_t tmp0 = __builtin_neon_vreinterpretv4siv4sf(_a); + const _i32x4_t tmp1 = __builtin_neon_vreinterpretv4siv4sf(_b); + const _i32x4_t tmp2 = __builtin_neon_vceqv4si(tmp0, tmp1, 1); + const float4_t result = __builtin_neon_vreinterpretv4sfv4si(tmp2); + + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_icmplt(float4_t _a, float4_t _b) + { + const _i32x4_t tmp0 = __builtin_neon_vreinterpretv4siv4sf(_a); + const _i32x4_t tmp1 = __builtin_neon_vreinterpretv4siv4sf(_b); + const _i32x4_t tmp2 = __builtin_neon_vcgtv4si(tmp1, tmp0, 1); + const float4_t result = __builtin_neon_vreinterpretv4sfv4si(tmp2); + + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_icmpgt(float4_t _a, float4_t _b) + { + const _i32x4_t tmp0 = __builtin_neon_vreinterpretv4siv4sf(_a); + const _i32x4_t tmp1 = __builtin_neon_vreinterpretv4siv4sf(_b); + const _i32x4_t tmp2 = __builtin_neon_vcgtv4si(tmp0, tmp1, 1); + const float4_t result = __builtin_neon_vreinterpretv4sfv4si(tmp2); + + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_imin(float4_t _a, float4_t _b) + { + const _i32x4_t tmp0 = __builtin_neon_vreinterpretv4siv4sf(_a); + const _i32x4_t tmp1 = __builtin_neon_vreinterpretv4siv4sf(_b); + const _i32x4_t tmp2 = __builtin_neon_vminv4si(tmp0, tmp1, 1); + const float4_t result = __builtin_neon_vreinterpretv4sfv4si(tmp2); + + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_imax(float4_t _a, float4_t _b) + { + const _i32x4_t tmp0 = __builtin_neon_vreinterpretv4siv4sf(_a); + const _i32x4_t tmp1 = __builtin_neon_vreinterpretv4siv4sf(_b); + const _i32x4_t tmp2 = __builtin_neon_vmaxv4si(tmp0, tmp1, 1); + const float4_t result = __builtin_neon_vreinterpretv4sfv4si(tmp2); + + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_iadd(float4_t _a, float4_t _b) + { + const _i32x4_t tmp0 = __builtin_neon_vreinterpretv4siv4sf(_a); + const _i32x4_t tmp1 = __builtin_neon_vreinterpretv4siv4sf(_b); + const _i32x4_t tmp2 = __builtin_neon_vaddv4si(tmp0, tmp1, 1); + const float4_t result = __builtin_neon_vreinterpretv4sfv4si(tmp2); + + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_isub(float4_t _a, float4_t _b) + { + const _i32x4_t tmp0 = __builtin_neon_vreinterpretv4siv4sf(_a); + const _i32x4_t tmp1 = __builtin_neon_vreinterpretv4siv4sf(_b); + const _i32x4_t tmp2 = __builtin_neon_vsubv4si(tmp0, tmp1, 1); + const float4_t result = __builtin_neon_vreinterpretv4sfv4si(tmp2); + + return result; + } + +} // namespace bx + +#define float4_shuf_xAzC float4_shuf_xAzC_ni +#define float4_shuf_yBwD float4_shuf_yBwD_ni +#define float4_rcp float4_rcp_ni +#define float4_orx float4_orx_ni +#define float4_orc float4_orc_ni +#define float4_neg float4_neg_ni +#define float4_madd float4_madd_ni +#define float4_nmsub float4_nmsub_ni +#define float4_div_nr float4_div_nr_ni +#define float4_div float4_div_nr_ni +#define float4_selb float4_selb_ni +#define float4_sels float4_sels_ni +#define float4_not float4_not_ni +#define float4_abs float4_abs_ni +#define float4_clamp float4_clamp_ni +#define float4_lerp float4_lerp_ni +#define float4_rsqrt float4_rsqrt_ni +#define float4_rsqrt_nr float4_rsqrt_nr_ni +#define float4_rsqrt_carmack float4_rsqrt_carmack_ni +#define float4_sqrt_nr float4_sqrt_nr_ni +#define float4_sqrt float4_sqrt_nr_ni +#define float4_log2 float4_log2_ni +#define float4_exp2 float4_exp2_ni +#define float4_pow float4_pow_ni +#define float4_cross3 float4_cross3_ni +#define float4_normalize3 float4_normalize3_ni +#define float4_dot3 float4_dot3_ni +#define float4_dot float4_dot_ni +#define float4_ceil float4_ceil_ni +#define float4_floor float4_floor_ni + +#include "float4_ni.h" + +namespace bx +{ +#define IMPLEMENT_TEST(_xyzw, _swizzle) \ + BX_FLOAT4_FORCE_INLINE bool float4_test_any_##_xyzw(float4_t _test) \ + { \ + const float4_t tmp0 = float4_swiz_##_swizzle(_test); \ + return float4_test_any_ni(tmp0); \ + } \ + \ + BX_FLOAT4_FORCE_INLINE bool float4_test_all_##_xyzw(float4_t _test) \ + { \ + const float4_t tmp0 = float4_swiz_##_swizzle(_test); \ + return float4_test_all_ni(tmp0); \ + } + +IMPLEMENT_TEST(x , xxxx); +IMPLEMENT_TEST(y , yyyy); +IMPLEMENT_TEST(xy , xyyy); +IMPLEMENT_TEST(z , zzzz); +IMPLEMENT_TEST(xz , xzzz); +IMPLEMENT_TEST(yz , yzzz); +IMPLEMENT_TEST(xyz , xyzz); +IMPLEMENT_TEST(w , wwww); +IMPLEMENT_TEST(xw , xwww); +IMPLEMENT_TEST(yw , ywww); +IMPLEMENT_TEST(xyw , xyww); +IMPLEMENT_TEST(zw , zwww); +IMPLEMENT_TEST(xzw , xzww); +IMPLEMENT_TEST(yzw , yzww); + + BX_FLOAT4_FORCE_INLINE bool float4_test_any_xyzw(float4_t _test) + { + return float4_test_any_ni(_test); + } + + BX_FLOAT4_FORCE_INLINE bool float4_test_all_xyzw(float4_t _test) + { + return float4_test_all_ni(_test); + } + +#undef IMPLEMENT_TEST +} // namespace bx + +#endif // BX_FLOAT4_NEON_H_HEADER_GUARD diff --git a/deps/include/bx/float4_ni.h b/deps/include/bx/float4_ni.h new file mode 100644 index 0000000..c709151 --- /dev/null +++ b/deps/include/bx/float4_ni.h @@ -0,0 +1,495 @@ +/* + * Copyright 2010-2015 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#ifndef BX_FLOAT4_NI_H_HEADER_GUARD +#define BX_FLOAT4_NI_H_HEADER_GUARD + +namespace bx +{ + BX_FLOAT4_INLINE float4_t float4_rcp_ni(float4_t _a); + + BX_FLOAT4_INLINE float4_t float4_shuf_xAzC_ni(float4_t _a, float4_t _b) + { + const float4_t xAyB = float4_shuf_xAyB(_a, _b); + const float4_t zCwD = float4_shuf_zCwD(_a, _b); + const float4_t result = float4_shuf_xyAB(xAyB, zCwD); + + return result; + } + + BX_FLOAT4_INLINE float4_t float4_shuf_yBwD_ni(float4_t _a, float4_t _b) + { + const float4_t xAyB = float4_shuf_xAyB(_a, _b); + const float4_t zCwD = float4_shuf_zCwD(_a, _b); + const float4_t result = float4_shuf_zwCD(xAyB, zCwD); + + return result; + } + + BX_FLOAT4_INLINE float4_t float4_madd_ni(float4_t _a, float4_t _b, float4_t _c) + { + const float4_t mul = float4_mul(_a, _b); + const float4_t result = float4_add(mul, _c); + + return result; + } + + BX_FLOAT4_INLINE float4_t float4_nmsub_ni(float4_t _a, float4_t _b, float4_t _c) + { + const float4_t mul = float4_mul(_a, _b); + const float4_t result = float4_sub(_c, mul); + + return result; + } + + BX_FLOAT4_INLINE float4_t float4_div_nr_ni(float4_t _a, float4_t _b) + { + const float4_t oneish = float4_isplat(0x3f800001); + const float4_t est = float4_rcp_est(_b); + const float4_t iter0 = float4_mul(_a, est); + const float4_t tmp1 = float4_nmsub(_b, est, oneish); + const float4_t result = float4_madd(tmp1, iter0, iter0); + + return result; + } + + BX_FLOAT4_INLINE float4_t float4_rcp_ni(float4_t _a) + { + const float4_t one = float4_splat(1.0f); + const float4_t result = float4_div(one, _a); + + return result; + } + + BX_FLOAT4_INLINE float4_t float4_orx_ni(float4_t _a) + { + const float4_t zwxy = float4_swiz_zwxy(_a); + const float4_t tmp0 = float4_or(_a, zwxy); + const float4_t tmp1 = float4_swiz_yyyy(_a); + const float4_t tmp2 = float4_or(tmp0, tmp1); + const float4_t mf000 = float4_ild(UINT32_MAX, 0, 0, 0); + const float4_t result = float4_and(tmp2, mf000); + + return result; + } + + BX_FLOAT4_INLINE float4_t float4_orc_ni(float4_t _a, float4_t _b) + { + const float4_t aorb = float4_or(_a, _b); + const float4_t mffff = float4_isplat(UINT32_MAX); + const float4_t result = float4_xor(aorb, mffff); + + return result; + } + + BX_FLOAT4_INLINE float4_t float4_neg_ni(float4_t _a) + { + const float4_t zero = float4_zero(); + const float4_t result = float4_sub(zero, _a); + + return result; + } + + BX_FLOAT4_INLINE float4_t float4_selb_ni(float4_t _mask, float4_t _a, float4_t _b) + { + const float4_t sel_a = float4_and(_a, _mask); + const float4_t sel_b = float4_andc(_b, _mask); + const float4_t result = float4_or(sel_a, sel_b); + + return result; + } + + BX_FLOAT4_INLINE float4_t float4_sels_ni(float4_t _test, float4_t _a, float4_t _b) + { + const float4_t mask = float4_sra(_test, 31); + const float4_t result = float4_selb(mask, _a, _b); + + return result; + } + + BX_FLOAT4_INLINE float4_t float4_not_ni(float4_t _a) + { + const float4_t mffff = float4_isplat(UINT32_MAX); + const float4_t result = float4_xor(_a, mffff); + + return result; + } + + BX_FLOAT4_INLINE float4_t float4_min_ni(float4_t _a, float4_t _b) + { + const float4_t mask = float4_cmplt(_a, _b); + const float4_t result = float4_selb(mask, _a, _b); + + return result; + } + + BX_FLOAT4_INLINE float4_t float4_max_ni(float4_t _a, float4_t _b) + { + const float4_t mask = float4_cmpgt(_a, _b); + const float4_t result = float4_selb(mask, _a, _b); + + return result; + } + + BX_FLOAT4_INLINE float4_t float4_abs_ni(float4_t _a) + { + const float4_t a_neg = float4_neg(_a); + const float4_t result = float4_max(a_neg, _a); + + return result; + } + + BX_FLOAT4_INLINE float4_t float4_imin_ni(float4_t _a, float4_t _b) + { + const float4_t mask = float4_icmplt(_a, _b); + const float4_t result = float4_selb(mask, _a, _b); + + return result; + } + + BX_FLOAT4_INLINE float4_t float4_imax_ni(float4_t _a, float4_t _b) + { + const float4_t mask = float4_icmpgt(_a, _b); + const float4_t result = float4_selb(mask, _a, _b); + + return result; + } + + BX_FLOAT4_INLINE float4_t float4_clamp_ni(float4_t _a, float4_t _min, float4_t _max) + { + const float4_t tmp = float4_min(_a, _max); + const float4_t result = float4_max(tmp, _min); + + return result; + } + + BX_FLOAT4_INLINE float4_t float4_lerp_ni(float4_t _a, float4_t _b, float4_t _s) + { + const float4_t ba = float4_sub(_b, _a); + const float4_t result = float4_madd(_s, ba, _a); + + return result; + } + + BX_FLOAT4_INLINE float4_t float4_sqrt_nr_ni(float4_t _a) + { + const float4_t half = float4_splat(0.5f); + const float4_t one = float4_splat(1.0f); + const float4_t zero = float4_zero(); + const float4_t tmp0 = float4_rsqrt_est(_a); + const float4_t tmp1 = float4_madd(tmp0, _a, zero); + const float4_t tmp2 = float4_madd(tmp1, half, zero); + const float4_t tmp3 = float4_nmsub(tmp0, tmp1, one); + const float4_t result = float4_madd(tmp3, tmp2, tmp1); + + return result; + } + + BX_FLOAT4_INLINE float4_t float4_rsqrt_ni(float4_t _a) + { + const float4_t one = float4_splat(1.0f); + const float4_t sqrt = float4_sqrt(_a); + const float4_t result = float4_div(one, sqrt); + + return result; + } + + BX_FLOAT4_INLINE float4_t float4_rsqrt_nr_ni(float4_t _a) + { + const float4_t rsqrt = float4_rsqrt_est(_a); + const float4_t iter0 = float4_mul(_a, rsqrt); + const float4_t iter1 = float4_mul(iter0, rsqrt); + const float4_t half = float4_splat(0.5f); + const float4_t half_rsqrt = float4_mul(half, rsqrt); + const float4_t three = float4_splat(3.0f); + const float4_t three_sub_iter1 = float4_sub(three, iter1); + const float4_t result = float4_mul(half_rsqrt, three_sub_iter1); + + return result; + } + + BX_FLOAT4_INLINE float4_t float4_rsqrt_carmack_ni(float4_t _a) + { + const float4_t half = float4_splat(0.5f); + const float4_t ah = float4_mul(half, _a); + const float4_t ashift = float4_sra(_a, 1); + const float4_t magic = float4_isplat(0x5f3759df); + const float4_t msuba = float4_isub(magic, ashift); + const float4_t msubasq = float4_mul(msuba, msuba); + const float4_t tmp0 = float4_splat(1.5f); + const float4_t tmp1 = float4_mul(ah, msubasq); + const float4_t tmp2 = float4_sub(tmp0, tmp1); + const float4_t result = float4_mul(msuba, tmp2); + + return result; + } + + namespace float4_logexp_detail + { + BX_FLOAT4_INLINE float4_t float4_poly1(float4_t _a, float _b, float _c) + { + const float4_t bbbb = float4_splat(_b); + const float4_t cccc = float4_splat(_c); + const float4_t result = float4_madd(cccc, _a, bbbb); + + return result; + } + + BX_FLOAT4_INLINE float4_t float4_poly2(float4_t _a, float _b, float _c, float _d) + { + const float4_t bbbb = float4_splat(_b); + const float4_t poly = float4_poly1(_a, _c, _d); + const float4_t result = float4_madd(poly, _a, bbbb); + + return result; + } + + BX_FLOAT4_INLINE float4_t float4_poly3(float4_t _a, float _b, float _c, float _d, float _e) + { + const float4_t bbbb = float4_splat(_b); + const float4_t poly = float4_poly2(_a, _c, _d, _e); + const float4_t result = float4_madd(poly, _a, bbbb); + + return result; + } + + BX_FLOAT4_INLINE float4_t float4_poly4(float4_t _a, float _b, float _c, float _d, float _e, float _f) + { + const float4_t bbbb = float4_splat(_b); + const float4_t poly = float4_poly3(_a, _c, _d, _e, _f); + const float4_t result = float4_madd(poly, _a, bbbb); + + return result; + } + + BX_FLOAT4_INLINE float4_t float4_poly5(float4_t _a, float _b, float _c, float _d, float _e, float _f, float _g) + { + const float4_t bbbb = float4_splat(_b); + const float4_t poly = float4_poly4(_a, _c, _d, _e, _f, _g); + const float4_t result = float4_madd(poly, _a, bbbb); + + return result; + } + + BX_FLOAT4_INLINE float4_t float4_logpoly(float4_t _a) + { +#if 1 + const float4_t result = float4_poly5(_a + , 3.11578814719469302614f, -3.32419399085241980044f + , 2.59883907202499966007f, -1.23152682416275988241f + , 0.318212422185251071475f, -0.0344359067839062357313f + ); +#elif 0 + const float4_t result = float4_poly4(_a + , 2.8882704548164776201f, -2.52074962577807006663f + , 1.48116647521213171641f, -0.465725644288844778798f + , 0.0596515482674574969533f + ); +#elif 0 + const float4_t result = float4_poly3(_a + , 2.61761038894603480148f, -1.75647175389045657003f + , 0.688243882994381274313f, -0.107254423828329604454f + ); +#else + const float4_t result = float4_poly2(_a + , 2.28330284476918490682f, -1.04913055217340124191f + , 0.204446009836232697516f + ); +#endif + + return result; + } + + BX_FLOAT4_INLINE float4_t float4_exppoly(float4_t _a) + { +#if 1 + const float4_t result = float4_poly5(_a + , 9.9999994e-1f, 6.9315308e-1f + , 2.4015361e-1f, 5.5826318e-2f + , 8.9893397e-3f, 1.8775767e-3f + ); +#elif 0 + const float4_t result = float4_poly4(_a + , 1.0000026f, 6.9300383e-1f + , 2.4144275e-1f, 5.2011464e-2f + , 1.3534167e-2f + ); +#elif 0 + const float4_t result = float4_poly3(_a + , 9.9992520e-1f, 6.9583356e-1f + , 2.2606716e-1f, 7.8024521e-2f + ); +#else + const float4_t result = float4_poly2(_a + , 1.0017247f, 6.5763628e-1f + , 3.3718944e-1f + ); +#endif // 0 + + return result; + } + } // namespace float4_internal + + BX_FLOAT4_INLINE float4_t float4_log2_ni(float4_t _a) + { + const float4_t expmask = float4_isplat(0x7f800000); + const float4_t mantmask = float4_isplat(0x007fffff); + const float4_t one = float4_splat(1.0f); + + const float4_t c127 = float4_isplat(127); + const float4_t aexp = float4_and(_a, expmask); + const float4_t aexpsr = float4_srl(aexp, 23); + const float4_t tmp0 = float4_isub(aexpsr, c127); + const float4_t exp = float4_itof(tmp0); + + const float4_t amask = float4_and(_a, mantmask); + const float4_t mant = float4_or(amask, one); + + const float4_t poly = float4_logexp_detail::float4_logpoly(mant); + + const float4_t mandiff = float4_sub(mant, one); + const float4_t result = float4_madd(poly, mandiff, exp); + + return result; + } + + BX_FLOAT4_INLINE float4_t float4_exp2_ni(float4_t _a) + { + const float4_t min = float4_splat( 129.0f); + const float4_t max = float4_splat(-126.99999f); + const float4_t tmp0 = float4_min(_a, min); + const float4_t aaaa = float4_max(tmp0, max); + + const float4_t half = float4_splat(0.5f); + const float4_t tmp2 = float4_sub(aaaa, half); + const float4_t ipart = float4_ftoi(tmp2); + const float4_t iround = float4_itof(ipart); + const float4_t fpart = float4_sub(aaaa, iround); + + const float4_t c127 = float4_isplat(127); + const float4_t tmp5 = float4_iadd(ipart, c127); + const float4_t expipart = float4_sll(tmp5, 23); + + const float4_t expfpart = float4_logexp_detail::float4_exppoly(fpart); + + const float4_t result = float4_mul(expipart, expfpart); + + return result; + } + + BX_FLOAT4_INLINE float4_t float4_pow_ni(float4_t _a, float4_t _b) + { + const float4_t alog2 = float4_log2(_a); + const float4_t alog2b = float4_mul(alog2, _b); + const float4_t result = float4_exp2(alog2b); + + return result; + } + + BX_FLOAT4_INLINE float4_t float4_dot3_ni(float4_t _a, float4_t _b) + { + const float4_t xyzw = float4_mul(_a, _b); + const float4_t xxxx = float4_swiz_xxxx(xyzw); + const float4_t yyyy = float4_swiz_yyyy(xyzw); + const float4_t zzzz = float4_swiz_zzzz(xyzw); + const float4_t tmp1 = float4_add(xxxx, yyyy); + const float4_t result = float4_add(zzzz, tmp1); + return result; + } + + BX_FLOAT4_INLINE float4_t float4_cross3_ni(float4_t _a, float4_t _b) + { + // a.yzx * b.zxy - a.zxy * b.yzx == (a * b.yzx - a.yzx * b).yzx +#if 0 + const float4_t a_yzxw = float4_swiz_yzxw(_a); + const float4_t a_zxyw = float4_swiz_zxyw(_a); + const float4_t b_zxyw = float4_swiz_zxyw(_b); + const float4_t b_yzxw = float4_swiz_yzxw(_b); + const float4_t tmp = float4_mul(a_yzxw, b_zxyw); + const float4_t result = float4_nmsub(a_zxyw, b_yzxw, tmp); +#else + const float4_t a_yzxw = float4_swiz_yzxw(_a); + const float4_t b_yzxw = float4_swiz_yzxw(_b); + const float4_t tmp0 = float4_mul(_a, b_yzxw); + const float4_t tmp1 = float4_nmsub(a_yzxw, _b, tmp0); + const float4_t result = float4_swiz_yzxw(tmp1); +#endif + + return result; + } + + BX_FLOAT4_INLINE float4_t float4_normalize3_ni(float4_t _a) + { + const float4_t dot3 = float4_dot3(_a, _a); + const float4_t invSqrt = float4_rsqrt(dot3); + const float4_t result = float4_mul(_a, invSqrt); + + return result; + } + + BX_FLOAT4_INLINE float4_t float4_dot_ni(float4_t _a, float4_t _b) + { + const float4_t xyzw = float4_mul(_a, _b); + const float4_t yzwx = float4_swiz_yzwx(xyzw); + const float4_t tmp0 = float4_add(xyzw, yzwx); + const float4_t zwxy = float4_swiz_zwxy(tmp0); + const float4_t result = float4_add(tmp0, zwxy); + + return result; + } + + BX_FLOAT4_INLINE float4_t float4_ceil_ni(float4_t _a) + { + const float4_t tmp0 = float4_ftoi(_a); + const float4_t tmp1 = float4_itof(tmp0); + const float4_t mask = float4_cmplt(tmp1, _a); + const float4_t one = float4_splat(1.0f); + const float4_t tmp2 = float4_and(one, mask); + const float4_t result = float4_add(tmp1, tmp2); + + return result; + } + + BX_FLOAT4_INLINE float4_t float4_floor_ni(float4_t _a) + { + const float4_t tmp0 = float4_ftoi(_a); + const float4_t tmp1 = float4_itof(tmp0); + const float4_t mask = float4_cmpgt(tmp1, _a); + const float4_t one = float4_splat(1.0f); + const float4_t tmp2 = float4_and(one, mask); + const float4_t result = float4_sub(tmp1, tmp2); + + return result; + } + + BX_FLOAT4_INLINE bool float4_test_any_ni(float4_t _a) + { + const float4_t mask = float4_sra(_a, 31); + const float4_t zwxy = float4_swiz_zwxy(mask); + const float4_t tmp0 = float4_or(mask, zwxy); + const float4_t tmp1 = float4_swiz_yyyy(tmp0); + const float4_t tmp2 = float4_or(tmp0, tmp1); + int res; + float4_stx(&res, tmp2); + return 0 != res; + } + + BX_FLOAT4_INLINE bool float4_test_all_ni(float4_t _a) + { + const float4_t bits = float4_sra(_a, 31); + const float4_t m1248 = float4_ild(1, 2, 4, 8); + const float4_t mask = float4_and(bits, m1248); + const float4_t zwxy = float4_swiz_zwxy(mask); + const float4_t tmp0 = float4_or(mask, zwxy); + const float4_t tmp1 = float4_swiz_yyyy(tmp0); + const float4_t tmp2 = float4_or(tmp0, tmp1); + int res; + float4_stx(&res, tmp2); + return 0xf == res; + } + +} // namespace bx + +#endif // BX_FLOAT4_NI_H_HEADER_GUARD diff --git a/deps/include/bx/float4_ref.h b/deps/include/bx/float4_ref.h new file mode 100644 index 0000000..277e2a7 --- /dev/null +++ b/deps/include/bx/float4_ref.h @@ -0,0 +1,604 @@ +/* + * Copyright 2010-2015 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#ifndef BX_FLOAT4_REF_H_HEADER_GUARD +#define BX_FLOAT4_REF_H_HEADER_GUARD + +#include // sqrtf + +namespace bx +{ + typedef union float4_t + { + float fxyzw[4]; + int32_t ixyzw[4]; + uint32_t uxyzw[4]; + + } float4_t; + +#define ELEMx 0 +#define ELEMy 1 +#define ELEMz 2 +#define ELEMw 3 +#define IMPLEMENT_SWIZZLE(_x, _y, _z, _w) \ + BX_FLOAT4_FORCE_INLINE float4_t float4_swiz_##_x##_y##_z##_w(float4_t _a) \ + { \ + float4_t result; \ + result.ixyzw[0] = _a.ixyzw[ELEM##_x]; \ + result.ixyzw[1] = _a.ixyzw[ELEM##_y]; \ + result.ixyzw[2] = _a.ixyzw[ELEM##_z]; \ + result.ixyzw[3] = _a.ixyzw[ELEM##_w]; \ + return result; \ + } + +#include "float4_swizzle.inl" + +#undef IMPLEMENT_SWIZZLE +#undef ELEMw +#undef ELEMz +#undef ELEMy +#undef ELEMx + +#define IMPLEMENT_TEST(_xyzw, _mask) \ + BX_FLOAT4_FORCE_INLINE bool float4_test_any_##_xyzw(float4_t _test) \ + { \ + uint32_t tmp = ( (_test.uxyzw[3]>>31)<<3) \ + | ( (_test.uxyzw[2]>>31)<<2) \ + | ( (_test.uxyzw[1]>>31)<<1) \ + | ( _test.uxyzw[0]>>31) \ + ; \ + return 0 != (tmp&(_mask) ); \ + } \ + \ + BX_FLOAT4_FORCE_INLINE bool float4_test_all_##_xyzw(float4_t _test) \ + { \ + uint32_t tmp = ( (_test.uxyzw[3]>>31)<<3) \ + | ( (_test.uxyzw[2]>>31)<<2) \ + | ( (_test.uxyzw[1]>>31)<<1) \ + | ( _test.uxyzw[0]>>31) \ + ; \ + return (_mask) == (tmp&(_mask) ); \ + } + +IMPLEMENT_TEST(x , 0x1); +IMPLEMENT_TEST(y , 0x2); +IMPLEMENT_TEST(xy , 0x3); +IMPLEMENT_TEST(z , 0x4); +IMPLEMENT_TEST(xz , 0x5); +IMPLEMENT_TEST(yz , 0x6); +IMPLEMENT_TEST(xyz , 0x7); +IMPLEMENT_TEST(w , 0x8); +IMPLEMENT_TEST(xw , 0x9); +IMPLEMENT_TEST(yw , 0xa); +IMPLEMENT_TEST(xyw , 0xb); +IMPLEMENT_TEST(zw , 0xc); +IMPLEMENT_TEST(xzw , 0xd); +IMPLEMENT_TEST(yzw , 0xe); +IMPLEMENT_TEST(xyzw , 0xf); + +#undef IMPLEMENT_TEST + + BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_xyAB(float4_t _a, float4_t _b) + { + float4_t result; + result.uxyzw[0] = _a.uxyzw[0]; + result.uxyzw[1] = _a.uxyzw[1]; + result.uxyzw[2] = _b.uxyzw[0]; + result.uxyzw[3] = _b.uxyzw[1]; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_ABxy(float4_t _a, float4_t _b) + { + float4_t result; + result.uxyzw[0] = _b.uxyzw[0]; + result.uxyzw[1] = _b.uxyzw[1]; + result.uxyzw[2] = _a.uxyzw[0]; + result.uxyzw[3] = _a.uxyzw[1]; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_CDzw(float4_t _a, float4_t _b) + { + float4_t result; + result.uxyzw[0] = _b.uxyzw[2]; + result.uxyzw[1] = _b.uxyzw[3]; + result.uxyzw[2] = _a.uxyzw[2]; + result.uxyzw[3] = _a.uxyzw[3]; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_zwCD(float4_t _a, float4_t _b) + { + float4_t result; + result.uxyzw[0] = _a.uxyzw[2]; + result.uxyzw[1] = _a.uxyzw[3]; + result.uxyzw[2] = _b.uxyzw[2]; + result.uxyzw[3] = _b.uxyzw[3]; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_xAyB(float4_t _a, float4_t _b) + { + float4_t result; + result.uxyzw[0] = _a.uxyzw[0]; + result.uxyzw[1] = _b.uxyzw[0]; + result.uxyzw[2] = _a.uxyzw[1]; + result.uxyzw[3] = _b.uxyzw[1]; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_yBxA(float4_t _a, float4_t _b) + { + float4_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]; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_zCwD(float4_t _a, float4_t _b) + { + float4_t result; + result.uxyzw[0] = _a.uxyzw[2]; + result.uxyzw[1] = _b.uxyzw[2]; + result.uxyzw[2] = _a.uxyzw[3]; + result.uxyzw[3] = _b.uxyzw[3]; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_CzDw(float4_t _a, float4_t _b) + { + float4_t result; + result.uxyzw[0] = _b.uxyzw[2]; + result.uxyzw[1] = _a.uxyzw[2]; + result.uxyzw[2] = _b.uxyzw[3]; + result.uxyzw[3] = _a.uxyzw[3]; + return result; + } + + BX_FLOAT4_FORCE_INLINE float float4_x(float4_t _a) + { + return _a.fxyzw[0]; + } + + BX_FLOAT4_FORCE_INLINE float float4_y(float4_t _a) + { + return _a.fxyzw[1]; + } + + BX_FLOAT4_FORCE_INLINE float float4_z(float4_t _a) + { + return _a.fxyzw[2]; + } + + BX_FLOAT4_FORCE_INLINE float float4_w(float4_t _a) + { + return _a.fxyzw[3]; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_ld(const void* _ptr) + { + const uint32_t* input = reinterpret_cast(_ptr); + float4_t result; + result.uxyzw[0] = input[0]; + result.uxyzw[1] = input[1]; + result.uxyzw[2] = input[2]; + result.uxyzw[3] = input[3]; + return result; + } + + BX_FLOAT4_FORCE_INLINE void float4_st(void* _ptr, float4_t _a) + { + uint32_t* result = reinterpret_cast(_ptr); + result[0] = _a.uxyzw[0]; + result[1] = _a.uxyzw[1]; + result[2] = _a.uxyzw[2]; + result[3] = _a.uxyzw[3]; + } + + BX_FLOAT4_FORCE_INLINE void float4_stx(void* _ptr, float4_t _a) + { + uint32_t* result = reinterpret_cast(_ptr); + result[0] = _a.uxyzw[0]; + } + + BX_FLOAT4_FORCE_INLINE void float4_stream(void* _ptr, float4_t _a) + { + uint32_t* result = reinterpret_cast(_ptr); + result[0] = _a.uxyzw[0]; + result[1] = _a.uxyzw[1]; + result[2] = _a.uxyzw[2]; + result[3] = _a.uxyzw[3]; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_ld(float _x, float _y, float _z, float _w) + { + float4_t result; + result.fxyzw[0] = _x; + result.fxyzw[1] = _y; + result.fxyzw[2] = _z; + result.fxyzw[3] = _w; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_ild(uint32_t _x, uint32_t _y, uint32_t _z, uint32_t _w) + { + float4_t result; + result.uxyzw[0] = _x; + result.uxyzw[1] = _y; + result.uxyzw[2] = _z; + result.uxyzw[3] = _w; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_splat(const void* _ptr) + { + const uint32_t val = *reinterpret_cast(_ptr); + float4_t result; + result.uxyzw[0] = val; + result.uxyzw[1] = val; + result.uxyzw[2] = val; + result.uxyzw[3] = val; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_splat(float _a) + { + return float4_ld(_a, _a, _a, _a); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_isplat(uint32_t _a) + { + return float4_ild(_a, _a, _a, _a); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_zero() + { + return float4_ild(0, 0, 0, 0); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_itof(float4_t _a) + { + float4_t result; + result.fxyzw[0] = (float)_a.ixyzw[0]; + result.fxyzw[1] = (float)_a.ixyzw[1]; + result.fxyzw[2] = (float)_a.ixyzw[2]; + result.fxyzw[3] = (float)_a.ixyzw[3]; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_ftoi(float4_t _a) + { + float4_t result; + result.ixyzw[0] = (int)_a.fxyzw[0]; + result.ixyzw[1] = (int)_a.fxyzw[1]; + result.ixyzw[2] = (int)_a.fxyzw[2]; + result.ixyzw[3] = (int)_a.fxyzw[3]; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_round(float4_t _a) + { + const float4_t tmp = float4_ftoi(_a); + const float4_t result = float4_itof(tmp); + + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_add(float4_t _a, float4_t _b) + { + float4_t result; + result.fxyzw[0] = _a.fxyzw[0] + _b.fxyzw[0]; + result.fxyzw[1] = _a.fxyzw[1] + _b.fxyzw[1]; + result.fxyzw[2] = _a.fxyzw[2] + _b.fxyzw[2]; + result.fxyzw[3] = _a.fxyzw[3] + _b.fxyzw[3]; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_sub(float4_t _a, float4_t _b) + { + float4_t result; + result.fxyzw[0] = _a.fxyzw[0] - _b.fxyzw[0]; + result.fxyzw[1] = _a.fxyzw[1] - _b.fxyzw[1]; + result.fxyzw[2] = _a.fxyzw[2] - _b.fxyzw[2]; + result.fxyzw[3] = _a.fxyzw[3] - _b.fxyzw[3]; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_mul(float4_t _a, float4_t _b) + { + float4_t result; + result.fxyzw[0] = _a.fxyzw[0] * _b.fxyzw[0]; + result.fxyzw[1] = _a.fxyzw[1] * _b.fxyzw[1]; + result.fxyzw[2] = _a.fxyzw[2] * _b.fxyzw[2]; + result.fxyzw[3] = _a.fxyzw[3] * _b.fxyzw[3]; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_div(float4_t _a, float4_t _b) + { + float4_t result; + result.fxyzw[0] = _a.fxyzw[0] / _b.fxyzw[0]; + result.fxyzw[1] = _a.fxyzw[1] / _b.fxyzw[1]; + result.fxyzw[2] = _a.fxyzw[2] / _b.fxyzw[2]; + result.fxyzw[3] = _a.fxyzw[3] / _b.fxyzw[3]; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_rcp_est(float4_t _a) + { + float4_t result; + result.fxyzw[0] = 1.0f / _a.fxyzw[0]; + result.fxyzw[1] = 1.0f / _a.fxyzw[1]; + result.fxyzw[2] = 1.0f / _a.fxyzw[2]; + result.fxyzw[3] = 1.0f / _a.fxyzw[3]; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_sqrt(float4_t _a) + { + float4_t result; + result.fxyzw[0] = sqrtf(_a.fxyzw[0]); + result.fxyzw[1] = sqrtf(_a.fxyzw[1]); + result.fxyzw[2] = sqrtf(_a.fxyzw[2]); + result.fxyzw[3] = sqrtf(_a.fxyzw[3]); + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_rsqrt_est(float4_t _a) + { + float4_t result; + result.fxyzw[0] = 1.0f / sqrtf(_a.fxyzw[0]); + result.fxyzw[1] = 1.0f / sqrtf(_a.fxyzw[1]); + result.fxyzw[2] = 1.0f / sqrtf(_a.fxyzw[2]); + result.fxyzw[3] = 1.0f / sqrtf(_a.fxyzw[3]); + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_cmpeq(float4_t _a, float4_t _b) + { + float4_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; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_cmplt(float4_t _a, float4_t _b) + { + float4_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; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_cmple(float4_t _a, float4_t _b) + { + float4_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; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_cmpgt(float4_t _a, float4_t _b) + { + float4_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; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_cmpge(float4_t _a, float4_t _b) + { + float4_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; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_min(float4_t _a, float4_t _b) + { + float4_t result; + result.fxyzw[0] = _a.fxyzw[0] < _b.fxyzw[0] ? _a.fxyzw[0] : _b.fxyzw[0]; + result.fxyzw[1] = _a.fxyzw[1] < _b.fxyzw[1] ? _a.fxyzw[1] : _b.fxyzw[1]; + result.fxyzw[2] = _a.fxyzw[2] < _b.fxyzw[2] ? _a.fxyzw[2] : _b.fxyzw[2]; + result.fxyzw[3] = _a.fxyzw[3] < _b.fxyzw[3] ? _a.fxyzw[3] : _b.fxyzw[3]; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_max(float4_t _a, float4_t _b) + { + float4_t result; + result.fxyzw[0] = _a.fxyzw[0] > _b.fxyzw[0] ? _a.fxyzw[0] : _b.fxyzw[0]; + result.fxyzw[1] = _a.fxyzw[1] > _b.fxyzw[1] ? _a.fxyzw[1] : _b.fxyzw[1]; + result.fxyzw[2] = _a.fxyzw[2] > _b.fxyzw[2] ? _a.fxyzw[2] : _b.fxyzw[2]; + result.fxyzw[3] = _a.fxyzw[3] > _b.fxyzw[3] ? _a.fxyzw[3] : _b.fxyzw[3]; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_and(float4_t _a, float4_t _b) + { + float4_t result; + result.uxyzw[0] = _a.uxyzw[0] & _b.uxyzw[0]; + result.uxyzw[1] = _a.uxyzw[1] & _b.uxyzw[1]; + result.uxyzw[2] = _a.uxyzw[2] & _b.uxyzw[2]; + result.uxyzw[3] = _a.uxyzw[3] & _b.uxyzw[3]; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_andc(float4_t _a, float4_t _b) + { + float4_t result; + result.uxyzw[0] = _a.uxyzw[0] & ~_b.uxyzw[0]; + result.uxyzw[1] = _a.uxyzw[1] & ~_b.uxyzw[1]; + result.uxyzw[2] = _a.uxyzw[2] & ~_b.uxyzw[2]; + result.uxyzw[3] = _a.uxyzw[3] & ~_b.uxyzw[3]; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_or(float4_t _a, float4_t _b) + { + float4_t result; + result.uxyzw[0] = _a.uxyzw[0] | _b.uxyzw[0]; + result.uxyzw[1] = _a.uxyzw[1] | _b.uxyzw[1]; + result.uxyzw[2] = _a.uxyzw[2] | _b.uxyzw[2]; + result.uxyzw[3] = _a.uxyzw[3] | _b.uxyzw[3]; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_xor(float4_t _a, float4_t _b) + { + float4_t result; + result.uxyzw[0] = _a.uxyzw[0] ^ _b.uxyzw[0]; + result.uxyzw[1] = _a.uxyzw[1] ^ _b.uxyzw[1]; + result.uxyzw[2] = _a.uxyzw[2] ^ _b.uxyzw[2]; + result.uxyzw[3] = _a.uxyzw[3] ^ _b.uxyzw[3]; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_sll(float4_t _a, int _count) + { + float4_t result; + result.uxyzw[0] = _a.uxyzw[0] << _count; + result.uxyzw[1] = _a.uxyzw[1] << _count; + result.uxyzw[2] = _a.uxyzw[2] << _count; + result.uxyzw[3] = _a.uxyzw[3] << _count; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_srl(float4_t _a, int _count) + { + float4_t result; + result.uxyzw[0] = _a.uxyzw[0] >> _count; + result.uxyzw[1] = _a.uxyzw[1] >> _count; + result.uxyzw[2] = _a.uxyzw[2] >> _count; + result.uxyzw[3] = _a.uxyzw[3] >> _count; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_sra(float4_t _a, int _count) + { + float4_t result; + result.ixyzw[0] = _a.ixyzw[0] >> _count; + result.ixyzw[1] = _a.ixyzw[1] >> _count; + result.ixyzw[2] = _a.ixyzw[2] >> _count; + result.ixyzw[3] = _a.ixyzw[3] >> _count; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_icmpeq(float4_t _a, float4_t _b) + { + float4_t result; + result.ixyzw[0] = _a.ixyzw[0] == _b.ixyzw[0] ? 0xffffffff : 0x0; + result.ixyzw[1] = _a.ixyzw[1] == _b.ixyzw[1] ? 0xffffffff : 0x0; + result.ixyzw[2] = _a.ixyzw[2] == _b.ixyzw[2] ? 0xffffffff : 0x0; + result.ixyzw[3] = _a.ixyzw[3] == _b.ixyzw[3] ? 0xffffffff : 0x0; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_icmplt(float4_t _a, float4_t _b) + { + float4_t result; + result.ixyzw[0] = _a.ixyzw[0] < _b.ixyzw[0] ? 0xffffffff : 0x0; + result.ixyzw[1] = _a.ixyzw[1] < _b.ixyzw[1] ? 0xffffffff : 0x0; + result.ixyzw[2] = _a.ixyzw[2] < _b.ixyzw[2] ? 0xffffffff : 0x0; + result.ixyzw[3] = _a.ixyzw[3] < _b.ixyzw[3] ? 0xffffffff : 0x0; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_icmpgt(float4_t _a, float4_t _b) + { + float4_t result; + result.ixyzw[0] = _a.ixyzw[0] > _b.ixyzw[0] ? 0xffffffff : 0x0; + result.ixyzw[1] = _a.ixyzw[1] > _b.ixyzw[1] ? 0xffffffff : 0x0; + result.ixyzw[2] = _a.ixyzw[2] > _b.ixyzw[2] ? 0xffffffff : 0x0; + result.ixyzw[3] = _a.ixyzw[3] > _b.ixyzw[3] ? 0xffffffff : 0x0; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_imin(float4_t _a, float4_t _b) + { + float4_t result; + result.ixyzw[0] = _a.ixyzw[0] < _b.ixyzw[0] ? _a.ixyzw[0] : _b.ixyzw[0]; + result.ixyzw[1] = _a.ixyzw[1] < _b.ixyzw[1] ? _a.ixyzw[1] : _b.ixyzw[1]; + result.ixyzw[2] = _a.ixyzw[2] < _b.ixyzw[2] ? _a.ixyzw[2] : _b.ixyzw[2]; + result.ixyzw[3] = _a.ixyzw[3] < _b.ixyzw[3] ? _a.ixyzw[3] : _b.ixyzw[3]; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_imax(float4_t _a, float4_t _b) + { + float4_t result; + result.ixyzw[0] = _a.ixyzw[0] > _b.ixyzw[0] ? _a.ixyzw[0] : _b.ixyzw[0]; + result.ixyzw[1] = _a.ixyzw[1] > _b.ixyzw[1] ? _a.ixyzw[1] : _b.ixyzw[1]; + result.ixyzw[2] = _a.ixyzw[2] > _b.ixyzw[2] ? _a.ixyzw[2] : _b.ixyzw[2]; + result.ixyzw[3] = _a.ixyzw[3] > _b.ixyzw[3] ? _a.ixyzw[3] : _b.ixyzw[3]; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_iadd(float4_t _a, float4_t _b) + { + float4_t result; + result.ixyzw[0] = _a.ixyzw[0] + _b.ixyzw[0]; + result.ixyzw[1] = _a.ixyzw[1] + _b.ixyzw[1]; + result.ixyzw[2] = _a.ixyzw[2] + _b.ixyzw[2]; + result.ixyzw[3] = _a.ixyzw[3] + _b.ixyzw[3]; + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_isub(float4_t _a, float4_t _b) + { + float4_t result; + result.ixyzw[0] = _a.ixyzw[0] - _b.ixyzw[0]; + result.ixyzw[1] = _a.ixyzw[1] - _b.ixyzw[1]; + result.ixyzw[2] = _a.ixyzw[2] - _b.ixyzw[2]; + result.ixyzw[3] = _a.ixyzw[3] - _b.ixyzw[3]; + return result; + } + +} // namespace bx + +#define float4_shuf_xAzC float4_shuf_xAzC_ni +#define float4_shuf_yBwD float4_shuf_yBwD_ni +#define float4_rcp float4_rcp_ni +#define float4_orx float4_orx_ni +#define float4_orc float4_orc_ni +#define float4_neg float4_neg_ni +#define float4_madd float4_madd_ni +#define float4_nmsub float4_nmsub_ni +#define float4_div_nr float4_div_nr_ni +#define float4_selb float4_selb_ni +#define float4_sels float4_sels_ni +#define float4_not float4_not_ni +#define float4_abs float4_abs_ni +#define float4_clamp float4_clamp_ni +#define float4_lerp float4_lerp_ni +#define float4_rsqrt float4_rsqrt_ni +#define float4_rsqrt_nr float4_rsqrt_nr_ni +#define float4_rsqrt_carmack float4_rsqrt_carmack_ni +#define float4_sqrt_nr float4_sqrt_nr_ni +#define float4_log2 float4_log2_ni +#define float4_exp2 float4_exp2_ni +#define float4_pow float4_pow_ni +#define float4_cross3 float4_cross3_ni +#define float4_normalize3 float4_normalize3_ni +#define float4_dot3 float4_dot3_ni +#define float4_dot float4_dot_ni +#define float4_ceil float4_ceil_ni +#define float4_floor float4_floor_ni +#include "float4_ni.h" + +#endif // BX_FLOAT4_REF_H_HEADER_GUARD diff --git a/deps/include/bx/float4_sse.h b/deps/include/bx/float4_sse.h new file mode 100644 index 0000000..070d201 --- /dev/null +++ b/deps/include/bx/float4_sse.h @@ -0,0 +1,461 @@ +/* + * Copyright 2010-2015 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#ifndef BX_FLOAT4_SSE_H_HEADER_GUARD +#define BX_FLOAT4_SSE_H_HEADER_GUARD + +#include // __m128i +#if defined(__SSE4_1__) +# include +#endif // defined(__SSE4_1__) +#include // __m128 + +namespace bx +{ + typedef __m128 float4_t; + +#define ELEMx 0 +#define ELEMy 1 +#define ELEMz 2 +#define ELEMw 3 +#define IMPLEMENT_SWIZZLE(_x, _y, _z, _w) \ + BX_FLOAT4_FORCE_INLINE float4_t float4_swiz_##_x##_y##_z##_w(float4_t _a) \ + { \ + return _mm_shuffle_ps( _a, _a, _MM_SHUFFLE(ELEM##_w, ELEM##_z, ELEM##_y, ELEM##_x ) ); \ + } + +#include "float4_swizzle.inl" + +#undef IMPLEMENT_SWIZZLE +#undef ELEMw +#undef ELEMz +#undef ELEMy +#undef ELEMx + +#define IMPLEMENT_TEST(_xyzw, _mask) \ + BX_FLOAT4_FORCE_INLINE bool float4_test_any_##_xyzw(float4_t _test) \ + { \ + return 0x0 != (_mm_movemask_ps(_test)&(_mask) ); \ + } \ + \ + BX_FLOAT4_FORCE_INLINE bool float4_test_all_##_xyzw(float4_t _test) \ + { \ + return (_mask) == (_mm_movemask_ps(_test)&(_mask) ); \ + } + +IMPLEMENT_TEST(x , 0x1); +IMPLEMENT_TEST(y , 0x2); +IMPLEMENT_TEST(xy , 0x3); +IMPLEMENT_TEST(z , 0x4); +IMPLEMENT_TEST(xz , 0x5); +IMPLEMENT_TEST(yz , 0x6); +IMPLEMENT_TEST(xyz , 0x7); +IMPLEMENT_TEST(w , 0x8); +IMPLEMENT_TEST(xw , 0x9); +IMPLEMENT_TEST(yw , 0xa); +IMPLEMENT_TEST(xyw , 0xb); +IMPLEMENT_TEST(zw , 0xc); +IMPLEMENT_TEST(xzw , 0xd); +IMPLEMENT_TEST(yzw , 0xe); +IMPLEMENT_TEST(xyzw , 0xf); + +#undef IMPLEMENT_TEST + + BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_xyAB(float4_t _a, float4_t _b) + { + return _mm_movelh_ps(_a, _b); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_ABxy(float4_t _a, float4_t _b) + { + return _mm_movelh_ps(_b, _a); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_CDzw(float4_t _a, float4_t _b) + { + return _mm_movehl_ps(_a, _b); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_zwCD(float4_t _a, float4_t _b) + { + return _mm_movehl_ps(_b, _a); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_xAyB(float4_t _a, float4_t _b) + { + return _mm_unpacklo_ps(_a, _b); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_yBxA(float4_t _a, float4_t _b) + { + return _mm_unpacklo_ps(_b, _a); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_zCwD(float4_t _a, float4_t _b) + { + return _mm_unpackhi_ps(_a, _b); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_CzDw(float4_t _a, float4_t _b) + { + return _mm_unpackhi_ps(_b, _a); + } + + BX_FLOAT4_FORCE_INLINE float float4_x(float4_t _a) + { + return _mm_cvtss_f32(_a); + } + + BX_FLOAT4_FORCE_INLINE float float4_y(float4_t _a) + { + const float4_t yyyy = float4_swiz_yyyy(_a); + const float result = _mm_cvtss_f32(yyyy); + + return result; + } + + BX_FLOAT4_FORCE_INLINE float float4_z(float4_t _a) + { + const float4_t zzzz = float4_swiz_zzzz(_a); + const float result = _mm_cvtss_f32(zzzz); + + return result; + } + + BX_FLOAT4_FORCE_INLINE float float4_w(float4_t _a) + { + const float4_t wwww = float4_swiz_wwww(_a); + const float result = _mm_cvtss_f32(wwww); + + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_ld(const void* _ptr) + { + return _mm_load_ps(reinterpret_cast(_ptr) ); + } + + BX_FLOAT4_FORCE_INLINE void float4_st(void* _ptr, float4_t _a) + { + _mm_store_ps(reinterpret_cast(_ptr), _a); + } + + BX_FLOAT4_FORCE_INLINE void float4_stx(void* _ptr, float4_t _a) + { + _mm_store_ss(reinterpret_cast(_ptr), _a); + } + + BX_FLOAT4_FORCE_INLINE void float4_stream(void* _ptr, float4_t _a) + { + _mm_stream_ps(reinterpret_cast(_ptr), _a); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_ld(float _x, float _y, float _z, float _w) + { + return _mm_set_ps(_w, _z, _y, _x); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_ild(uint32_t _x, uint32_t _y, uint32_t _z, uint32_t _w) + { + const __m128i set = _mm_set_epi32(_w, _z, _y, _x); + const float4_t result = _mm_castsi128_ps(set); + + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_splat(const void* _ptr) + { + const float4_t x___ = _mm_load_ss(reinterpret_cast(_ptr) ); + const float4_t result = float4_swiz_xxxx(x___); + + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_splat(float _a) + { + return _mm_set1_ps(_a); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_isplat(uint32_t _a) + { + const __m128i splat = _mm_set1_epi32(_a); + const float4_t result = _mm_castsi128_ps(splat); + + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_zero() + { + return _mm_setzero_ps(); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_itof(float4_t _a) + { + const __m128i itof = _mm_castps_si128(_a); + const float4_t result = _mm_cvtepi32_ps(itof); + + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_ftoi(float4_t _a) + { + const __m128i ftoi = _mm_cvtps_epi32(_a); + const float4_t result = _mm_castsi128_ps(ftoi); + + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_round(float4_t _a) + { +#if defined(__SSE4_1__) + return _mm_round_ps(_a, _MM_FROUND_NINT); +#else + const __m128i round = _mm_cvtps_epi32(_a); + const float4_t result = _mm_cvtepi32_ps(round); + + return result; +#endif // defined(__SSE4_1__) + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_add(float4_t _a, float4_t _b) + { + return _mm_add_ps(_a, _b); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_sub(float4_t _a, float4_t _b) + { + return _mm_sub_ps(_a, _b); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_mul(float4_t _a, float4_t _b) + { + return _mm_mul_ps(_a, _b); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_div(float4_t _a, float4_t _b) + { + return _mm_div_ps(_a, _b); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_rcp_est(float4_t _a) + { + return _mm_rcp_ps(_a); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_sqrt(float4_t _a) + { + return _mm_sqrt_ps(_a); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_rsqrt_est(float4_t _a) + { + return _mm_rsqrt_ps(_a); + } + +#if defined(__SSE4_1__) + BX_FLOAT4_FORCE_INLINE float4_t float4_dot3(float4_t _a, float4_t _b) + { + return _mm_dp_ps(_a, _b, 0x77); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_dot(float4_t _a, float4_t _b) + { + return _mm_dp_ps(_a, _b, 0xFF); + } +#endif // defined(__SSE4__) + + BX_FLOAT4_FORCE_INLINE float4_t float4_cmpeq(float4_t _a, float4_t _b) + { + return _mm_cmpeq_ps(_a, _b); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_cmplt(float4_t _a, float4_t _b) + { + return _mm_cmplt_ps(_a, _b); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_cmple(float4_t _a, float4_t _b) + { + return _mm_cmple_ps(_a, _b); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_cmpgt(float4_t _a, float4_t _b) + { + return _mm_cmpgt_ps(_a, _b); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_cmpge(float4_t _a, float4_t _b) + { + return _mm_cmpge_ps(_a, _b); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_min(float4_t _a, float4_t _b) + { + return _mm_min_ps(_a, _b); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_max(float4_t _a, float4_t _b) + { + return _mm_max_ps(_a, _b); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_and(float4_t _a, float4_t _b) + { + return _mm_and_ps(_a, _b); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_andc(float4_t _a, float4_t _b) + { + return _mm_andnot_ps(_b, _a); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_or(float4_t _a, float4_t _b) + { + return _mm_or_ps(_a, _b); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_xor(float4_t _a, float4_t _b) + { + return _mm_xor_ps(_a, _b); + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_sll(float4_t _a, int _count) + { + const __m128i a = _mm_castps_si128(_a); + const __m128i shift = _mm_slli_epi32(a, _count); + const float4_t result = _mm_castsi128_ps(shift); + + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_srl(float4_t _a, int _count) + { + const __m128i a = _mm_castps_si128(_a); + const __m128i shift = _mm_srli_epi32(a, _count); + const float4_t result = _mm_castsi128_ps(shift); + + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_sra(float4_t _a, int _count) + { + const __m128i a = _mm_castps_si128(_a); + const __m128i shift = _mm_srai_epi32(a, _count); + const float4_t result = _mm_castsi128_ps(shift); + + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_icmpeq(float4_t _a, float4_t _b) + { + const __m128i tmp0 = _mm_castps_si128(_a); + const __m128i tmp1 = _mm_castps_si128(_b); + const __m128i tmp2 = _mm_cmpeq_epi32(tmp0, tmp1); + const float4_t result = _mm_castsi128_ps(tmp2); + + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_icmplt(float4_t _a, float4_t _b) + { + const __m128i tmp0 = _mm_castps_si128(_a); + const __m128i tmp1 = _mm_castps_si128(_b); + const __m128i tmp2 = _mm_cmplt_epi32(tmp0, tmp1); + const float4_t result = _mm_castsi128_ps(tmp2); + + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_icmpgt(float4_t _a, float4_t _b) + { + const __m128i tmp0 = _mm_castps_si128(_a); + const __m128i tmp1 = _mm_castps_si128(_b); + const __m128i tmp2 = _mm_cmpgt_epi32(tmp0, tmp1); + const float4_t result = _mm_castsi128_ps(tmp2); + + return result; + } + +#if defined(__SSE4_1__) + BX_FLOAT4_FORCE_INLINE float4_t float4_imin(float4_t _a, float4_t _b) + { + const __m128i tmp0 = _mm_castps_si128(_a); + const __m128i tmp1 = _mm_castps_si128(_b); + const __m128i tmp2 = _mm_min_epi32(tmp0, tmp1); + const float4_t result = _mm_castsi128_ps(tmp2); + + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_imax(float4_t _a, float4_t _b) + { + const __m128i tmp0 = _mm_castps_si128(_a); + const __m128i tmp1 = _mm_castps_si128(_b); + const __m128i tmp2 = _mm_max_epi32(tmp0, tmp1); + const float4_t result = _mm_castsi128_ps(tmp2); + + return result; + } +#endif // defined(__SSE4_1__) + + BX_FLOAT4_FORCE_INLINE float4_t float4_iadd(float4_t _a, float4_t _b) + { + const __m128i a = _mm_castps_si128(_a); + const __m128i b = _mm_castps_si128(_b); + const __m128i add = _mm_add_epi32(a, b); + const float4_t result = _mm_castsi128_ps(add); + + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_isub(float4_t _a, float4_t _b) + { + const __m128i a = _mm_castps_si128(_a); + const __m128i b = _mm_castps_si128(_b); + const __m128i sub = _mm_sub_epi32(a, b); + const float4_t result = _mm_castsi128_ps(sub); + + return result; + } + +} // namespace bx + +#define float4_shuf_xAzC float4_shuf_xAzC_ni +#define float4_shuf_yBwD float4_shuf_yBwD_ni +#define float4_rcp float4_rcp_ni +#define float4_orx float4_orx_ni +#define float4_orc float4_orc_ni +#define float4_neg float4_neg_ni +#define float4_madd float4_madd_ni +#define float4_nmsub float4_nmsub_ni +#define float4_div_nr float4_div_nr_ni +#define float4_selb float4_selb_ni +#define float4_sels float4_sels_ni +#define float4_not float4_not_ni +#define float4_abs float4_abs_ni +#define float4_clamp float4_clamp_ni +#define float4_lerp float4_lerp_ni +#define float4_rsqrt float4_rsqrt_ni +#define float4_rsqrt_nr float4_rsqrt_nr_ni +#define float4_rsqrt_carmack float4_rsqrt_carmack_ni +#define float4_sqrt_nr float4_sqrt_nr_ni +#define float4_log2 float4_log2_ni +#define float4_exp2 float4_exp2_ni +#define float4_pow float4_pow_ni +#define float4_cross3 float4_cross3_ni +#define float4_normalize3 float4_normalize3_ni +#define float4_ceil float4_ceil_ni +#define float4_floor float4_floor_ni + +#if !defined(__SSE4_1__) +# define float4_dot3 float4_dot3_ni +# define float4_dot float4_dot_ni +# define float4_imin float4_imin_ni +# define float4_imax float4_imax_ni +#endif // defined(__SSE4_1__) + +#include "float4_ni.h" + +#endif // BX_FLOAT4_SSE_H_HEADER_GUARD diff --git a/deps/include/bx/float4_swizzle.inl b/deps/include/bx/float4_swizzle.inl new file mode 100644 index 0000000..f9429d6 --- /dev/null +++ b/deps/include/bx/float4_swizzle.inl @@ -0,0 +1,266 @@ +/* + * Copyright 2010-2015 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#ifndef BX_FLOAT4_T_H_HEADER_GUARD +# error "xmacro file, must be included from float4_*.h" +#endif // BX_FLOAT4_T_H_HEADER_GUARD + +// included from float4_t.h +IMPLEMENT_SWIZZLE(x, x, x, x) +IMPLEMENT_SWIZZLE(x, x, x, y) +IMPLEMENT_SWIZZLE(x, x, x, z) +IMPLEMENT_SWIZZLE(x, x, x, w) +IMPLEMENT_SWIZZLE(x, x, y, x) +IMPLEMENT_SWIZZLE(x, x, y, y) +IMPLEMENT_SWIZZLE(x, x, y, z) +IMPLEMENT_SWIZZLE(x, x, y, w) +IMPLEMENT_SWIZZLE(x, x, z, x) +IMPLEMENT_SWIZZLE(x, x, z, y) +IMPLEMENT_SWIZZLE(x, x, z, z) +IMPLEMENT_SWIZZLE(x, x, z, w) +IMPLEMENT_SWIZZLE(x, x, w, x) +IMPLEMENT_SWIZZLE(x, x, w, y) +IMPLEMENT_SWIZZLE(x, x, w, z) +IMPLEMENT_SWIZZLE(x, x, w, w) +IMPLEMENT_SWIZZLE(x, y, x, x) +IMPLEMENT_SWIZZLE(x, y, x, y) +IMPLEMENT_SWIZZLE(x, y, x, z) +IMPLEMENT_SWIZZLE(x, y, x, w) +IMPLEMENT_SWIZZLE(x, y, y, x) +IMPLEMENT_SWIZZLE(x, y, y, y) +IMPLEMENT_SWIZZLE(x, y, y, z) +IMPLEMENT_SWIZZLE(x, y, y, w) +IMPLEMENT_SWIZZLE(x, y, z, x) +IMPLEMENT_SWIZZLE(x, y, z, y) +IMPLEMENT_SWIZZLE(x, y, z, z) +// IMPLEMENT_SWIZZLE(x, y, z, w) +IMPLEMENT_SWIZZLE(x, y, w, x) +IMPLEMENT_SWIZZLE(x, y, w, y) +IMPLEMENT_SWIZZLE(x, y, w, z) +IMPLEMENT_SWIZZLE(x, y, w, w) +IMPLEMENT_SWIZZLE(x, z, x, x) +IMPLEMENT_SWIZZLE(x, z, x, y) +IMPLEMENT_SWIZZLE(x, z, x, z) +IMPLEMENT_SWIZZLE(x, z, x, w) +IMPLEMENT_SWIZZLE(x, z, y, x) +IMPLEMENT_SWIZZLE(x, z, y, y) +IMPLEMENT_SWIZZLE(x, z, y, z) +IMPLEMENT_SWIZZLE(x, z, y, w) +IMPLEMENT_SWIZZLE(x, z, z, x) +IMPLEMENT_SWIZZLE(x, z, z, y) +IMPLEMENT_SWIZZLE(x, z, z, z) +IMPLEMENT_SWIZZLE(x, z, z, w) +IMPLEMENT_SWIZZLE(x, z, w, x) +IMPLEMENT_SWIZZLE(x, z, w, y) +IMPLEMENT_SWIZZLE(x, z, w, z) +IMPLEMENT_SWIZZLE(x, z, w, w) +IMPLEMENT_SWIZZLE(x, w, x, x) +IMPLEMENT_SWIZZLE(x, w, x, y) +IMPLEMENT_SWIZZLE(x, w, x, z) +IMPLEMENT_SWIZZLE(x, w, x, w) +IMPLEMENT_SWIZZLE(x, w, y, x) +IMPLEMENT_SWIZZLE(x, w, y, y) +IMPLEMENT_SWIZZLE(x, w, y, z) +IMPLEMENT_SWIZZLE(x, w, y, w) +IMPLEMENT_SWIZZLE(x, w, z, x) +IMPLEMENT_SWIZZLE(x, w, z, y) +IMPLEMENT_SWIZZLE(x, w, z, z) +IMPLEMENT_SWIZZLE(x, w, z, w) +IMPLEMENT_SWIZZLE(x, w, w, x) +IMPLEMENT_SWIZZLE(x, w, w, y) +IMPLEMENT_SWIZZLE(x, w, w, z) +IMPLEMENT_SWIZZLE(x, w, w, w) +IMPLEMENT_SWIZZLE(y, x, x, x) +IMPLEMENT_SWIZZLE(y, x, x, y) +IMPLEMENT_SWIZZLE(y, x, x, z) +IMPLEMENT_SWIZZLE(y, x, x, w) +IMPLEMENT_SWIZZLE(y, x, y, x) +IMPLEMENT_SWIZZLE(y, x, y, y) +IMPLEMENT_SWIZZLE(y, x, y, z) +IMPLEMENT_SWIZZLE(y, x, y, w) +IMPLEMENT_SWIZZLE(y, x, z, x) +IMPLEMENT_SWIZZLE(y, x, z, y) +IMPLEMENT_SWIZZLE(y, x, z, z) +IMPLEMENT_SWIZZLE(y, x, z, w) +IMPLEMENT_SWIZZLE(y, x, w, x) +IMPLEMENT_SWIZZLE(y, x, w, y) +IMPLEMENT_SWIZZLE(y, x, w, z) +IMPLEMENT_SWIZZLE(y, x, w, w) +IMPLEMENT_SWIZZLE(y, y, x, x) +IMPLEMENT_SWIZZLE(y, y, x, y) +IMPLEMENT_SWIZZLE(y, y, x, z) +IMPLEMENT_SWIZZLE(y, y, x, w) +IMPLEMENT_SWIZZLE(y, y, y, x) +IMPLEMENT_SWIZZLE(y, y, y, y) +IMPLEMENT_SWIZZLE(y, y, y, z) +IMPLEMENT_SWIZZLE(y, y, y, w) +IMPLEMENT_SWIZZLE(y, y, z, x) +IMPLEMENT_SWIZZLE(y, y, z, y) +IMPLEMENT_SWIZZLE(y, y, z, z) +IMPLEMENT_SWIZZLE(y, y, z, w) +IMPLEMENT_SWIZZLE(y, y, w, x) +IMPLEMENT_SWIZZLE(y, y, w, y) +IMPLEMENT_SWIZZLE(y, y, w, z) +IMPLEMENT_SWIZZLE(y, y, w, w) +IMPLEMENT_SWIZZLE(y, z, x, x) +IMPLEMENT_SWIZZLE(y, z, x, y) +IMPLEMENT_SWIZZLE(y, z, x, z) +IMPLEMENT_SWIZZLE(y, z, x, w) +IMPLEMENT_SWIZZLE(y, z, y, x) +IMPLEMENT_SWIZZLE(y, z, y, y) +IMPLEMENT_SWIZZLE(y, z, y, z) +IMPLEMENT_SWIZZLE(y, z, y, w) +IMPLEMENT_SWIZZLE(y, z, z, x) +IMPLEMENT_SWIZZLE(y, z, z, y) +IMPLEMENT_SWIZZLE(y, z, z, z) +IMPLEMENT_SWIZZLE(y, z, z, w) +IMPLEMENT_SWIZZLE(y, z, w, x) +IMPLEMENT_SWIZZLE(y, z, w, y) +IMPLEMENT_SWIZZLE(y, z, w, z) +IMPLEMENT_SWIZZLE(y, z, w, w) +IMPLEMENT_SWIZZLE(y, w, x, x) +IMPLEMENT_SWIZZLE(y, w, x, y) +IMPLEMENT_SWIZZLE(y, w, x, z) +IMPLEMENT_SWIZZLE(y, w, x, w) +IMPLEMENT_SWIZZLE(y, w, y, x) +IMPLEMENT_SWIZZLE(y, w, y, y) +IMPLEMENT_SWIZZLE(y, w, y, z) +IMPLEMENT_SWIZZLE(y, w, y, w) +IMPLEMENT_SWIZZLE(y, w, z, x) +IMPLEMENT_SWIZZLE(y, w, z, y) +IMPLEMENT_SWIZZLE(y, w, z, z) +IMPLEMENT_SWIZZLE(y, w, z, w) +IMPLEMENT_SWIZZLE(y, w, w, x) +IMPLEMENT_SWIZZLE(y, w, w, y) +IMPLEMENT_SWIZZLE(y, w, w, z) +IMPLEMENT_SWIZZLE(y, w, w, w) +IMPLEMENT_SWIZZLE(z, x, x, x) +IMPLEMENT_SWIZZLE(z, x, x, y) +IMPLEMENT_SWIZZLE(z, x, x, z) +IMPLEMENT_SWIZZLE(z, x, x, w) +IMPLEMENT_SWIZZLE(z, x, y, x) +IMPLEMENT_SWIZZLE(z, x, y, y) +IMPLEMENT_SWIZZLE(z, x, y, z) +IMPLEMENT_SWIZZLE(z, x, y, w) +IMPLEMENT_SWIZZLE(z, x, z, x) +IMPLEMENT_SWIZZLE(z, x, z, y) +IMPLEMENT_SWIZZLE(z, x, z, z) +IMPLEMENT_SWIZZLE(z, x, z, w) +IMPLEMENT_SWIZZLE(z, x, w, x) +IMPLEMENT_SWIZZLE(z, x, w, y) +IMPLEMENT_SWIZZLE(z, x, w, z) +IMPLEMENT_SWIZZLE(z, x, w, w) +IMPLEMENT_SWIZZLE(z, y, x, x) +IMPLEMENT_SWIZZLE(z, y, x, y) +IMPLEMENT_SWIZZLE(z, y, x, z) +IMPLEMENT_SWIZZLE(z, y, x, w) +IMPLEMENT_SWIZZLE(z, y, y, x) +IMPLEMENT_SWIZZLE(z, y, y, y) +IMPLEMENT_SWIZZLE(z, y, y, z) +IMPLEMENT_SWIZZLE(z, y, y, w) +IMPLEMENT_SWIZZLE(z, y, z, x) +IMPLEMENT_SWIZZLE(z, y, z, y) +IMPLEMENT_SWIZZLE(z, y, z, z) +IMPLEMENT_SWIZZLE(z, y, z, w) +IMPLEMENT_SWIZZLE(z, y, w, x) +IMPLEMENT_SWIZZLE(z, y, w, y) +IMPLEMENT_SWIZZLE(z, y, w, z) +IMPLEMENT_SWIZZLE(z, y, w, w) +IMPLEMENT_SWIZZLE(z, z, x, x) +IMPLEMENT_SWIZZLE(z, z, x, y) +IMPLEMENT_SWIZZLE(z, z, x, z) +IMPLEMENT_SWIZZLE(z, z, x, w) +IMPLEMENT_SWIZZLE(z, z, y, x) +IMPLEMENT_SWIZZLE(z, z, y, y) +IMPLEMENT_SWIZZLE(z, z, y, z) +IMPLEMENT_SWIZZLE(z, z, y, w) +IMPLEMENT_SWIZZLE(z, z, z, x) +IMPLEMENT_SWIZZLE(z, z, z, y) +IMPLEMENT_SWIZZLE(z, z, z, z) +IMPLEMENT_SWIZZLE(z, z, z, w) +IMPLEMENT_SWIZZLE(z, z, w, x) +IMPLEMENT_SWIZZLE(z, z, w, y) +IMPLEMENT_SWIZZLE(z, z, w, z) +IMPLEMENT_SWIZZLE(z, z, w, w) +IMPLEMENT_SWIZZLE(z, w, x, x) +IMPLEMENT_SWIZZLE(z, w, x, y) +IMPLEMENT_SWIZZLE(z, w, x, z) +IMPLEMENT_SWIZZLE(z, w, x, w) +IMPLEMENT_SWIZZLE(z, w, y, x) +IMPLEMENT_SWIZZLE(z, w, y, y) +IMPLEMENT_SWIZZLE(z, w, y, z) +IMPLEMENT_SWIZZLE(z, w, y, w) +IMPLEMENT_SWIZZLE(z, w, z, x) +IMPLEMENT_SWIZZLE(z, w, z, y) +IMPLEMENT_SWIZZLE(z, w, z, z) +IMPLEMENT_SWIZZLE(z, w, z, w) +IMPLEMENT_SWIZZLE(z, w, w, x) +IMPLEMENT_SWIZZLE(z, w, w, y) +IMPLEMENT_SWIZZLE(z, w, w, z) +IMPLEMENT_SWIZZLE(z, w, w, w) +IMPLEMENT_SWIZZLE(w, x, x, x) +IMPLEMENT_SWIZZLE(w, x, x, y) +IMPLEMENT_SWIZZLE(w, x, x, z) +IMPLEMENT_SWIZZLE(w, x, x, w) +IMPLEMENT_SWIZZLE(w, x, y, x) +IMPLEMENT_SWIZZLE(w, x, y, y) +IMPLEMENT_SWIZZLE(w, x, y, z) +IMPLEMENT_SWIZZLE(w, x, y, w) +IMPLEMENT_SWIZZLE(w, x, z, x) +IMPLEMENT_SWIZZLE(w, x, z, y) +IMPLEMENT_SWIZZLE(w, x, z, z) +IMPLEMENT_SWIZZLE(w, x, z, w) +IMPLEMENT_SWIZZLE(w, x, w, x) +IMPLEMENT_SWIZZLE(w, x, w, y) +IMPLEMENT_SWIZZLE(w, x, w, z) +IMPLEMENT_SWIZZLE(w, x, w, w) +IMPLEMENT_SWIZZLE(w, y, x, x) +IMPLEMENT_SWIZZLE(w, y, x, y) +IMPLEMENT_SWIZZLE(w, y, x, z) +IMPLEMENT_SWIZZLE(w, y, x, w) +IMPLEMENT_SWIZZLE(w, y, y, x) +IMPLEMENT_SWIZZLE(w, y, y, y) +IMPLEMENT_SWIZZLE(w, y, y, z) +IMPLEMENT_SWIZZLE(w, y, y, w) +IMPLEMENT_SWIZZLE(w, y, z, x) +IMPLEMENT_SWIZZLE(w, y, z, y) +IMPLEMENT_SWIZZLE(w, y, z, z) +IMPLEMENT_SWIZZLE(w, y, z, w) +IMPLEMENT_SWIZZLE(w, y, w, x) +IMPLEMENT_SWIZZLE(w, y, w, y) +IMPLEMENT_SWIZZLE(w, y, w, z) +IMPLEMENT_SWIZZLE(w, y, w, w) +IMPLEMENT_SWIZZLE(w, z, x, x) +IMPLEMENT_SWIZZLE(w, z, x, y) +IMPLEMENT_SWIZZLE(w, z, x, z) +IMPLEMENT_SWIZZLE(w, z, x, w) +IMPLEMENT_SWIZZLE(w, z, y, x) +IMPLEMENT_SWIZZLE(w, z, y, y) +IMPLEMENT_SWIZZLE(w, z, y, z) +IMPLEMENT_SWIZZLE(w, z, y, w) +IMPLEMENT_SWIZZLE(w, z, z, x) +IMPLEMENT_SWIZZLE(w, z, z, y) +IMPLEMENT_SWIZZLE(w, z, z, z) +IMPLEMENT_SWIZZLE(w, z, z, w) +IMPLEMENT_SWIZZLE(w, z, w, x) +IMPLEMENT_SWIZZLE(w, z, w, y) +IMPLEMENT_SWIZZLE(w, z, w, z) +IMPLEMENT_SWIZZLE(w, z, w, w) +IMPLEMENT_SWIZZLE(w, w, x, x) +IMPLEMENT_SWIZZLE(w, w, x, y) +IMPLEMENT_SWIZZLE(w, w, x, z) +IMPLEMENT_SWIZZLE(w, w, x, w) +IMPLEMENT_SWIZZLE(w, w, y, x) +IMPLEMENT_SWIZZLE(w, w, y, y) +IMPLEMENT_SWIZZLE(w, w, y, z) +IMPLEMENT_SWIZZLE(w, w, y, w) +IMPLEMENT_SWIZZLE(w, w, z, x) +IMPLEMENT_SWIZZLE(w, w, z, y) +IMPLEMENT_SWIZZLE(w, w, z, z) +IMPLEMENT_SWIZZLE(w, w, z, w) +IMPLEMENT_SWIZZLE(w, w, w, x) +IMPLEMENT_SWIZZLE(w, w, w, y) +IMPLEMENT_SWIZZLE(w, w, w, z) +IMPLEMENT_SWIZZLE(w, w, w, w) diff --git a/deps/include/bx/float4_t.h b/deps/include/bx/float4_t.h new file mode 100644 index 0000000..6aacf4c --- /dev/null +++ b/deps/include/bx/float4_t.h @@ -0,0 +1,35 @@ +/* + * Copyright 2010-2015 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#ifndef BX_FLOAT4_T_H_HEADER_GUARD +#define BX_FLOAT4_T_H_HEADER_GUARD + +#include "bx.h" + +#define BX_FLOAT4_FORCE_INLINE BX_FORCE_INLINE +#define BX_FLOAT4_INLINE static inline + +#if defined(__SSE2__) || (BX_COMPILER_MSVC && (BX_ARCH_64BIT || _M_IX86_FP >= 2) ) +# include "float4_sse.h" +#elif defined(__ARM_NEON__) && !BX_COMPILER_CLANG +# include "float4_neon.h" +#elif BX_COMPILER_CLANG \ + && !BX_PLATFORM_EMSCRIPTEN \ + && !BX_PLATFORM_IOS \ + && BX_CLANG_HAS_EXTENSION(attribute_ext_vector_type) +# include "float4_langext.h" +#else +# ifndef BX_FLOAT4_WARN_REFERENCE_IMPL +# define BX_FLOAT4_WARN_REFERENCE_IMPL 0 +# endif // BX_FLOAT4_WARN_REFERENCE_IMPL + +# if BX_FLOAT4_WARN_REFERENCE_IMPL +# pragma message("************************************\nUsing SIMD reference implementation!\n************************************") +# endif // BX_FLOAT4_WARN_REFERENCE_IMPL + +# include "float4_ref.h" +#endif // + +#endif // BX_FLOAT4_T_H_HEADER_GUARD diff --git a/deps/include/bx/float4x4_t.h b/deps/include/bx/float4x4_t.h new file mode 100644 index 0000000..435aaec --- /dev/null +++ b/deps/include/bx/float4x4_t.h @@ -0,0 +1,158 @@ +/* + * Copyright 2010-2015 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#ifndef BX_FLOAT4X4_H_HEADER_GUARD +#define BX_FLOAT4X4_H_HEADER_GUARD + +#include "float4_t.h" + +namespace bx +{ + BX_ALIGN_DECL_16(struct) float4x4_t + { + float4_t col[4]; + }; + + BX_FLOAT4_FORCE_INLINE float4_t float4_mul_xyz1(float4_t _a, const float4x4_t* _b) + { + const float4_t xxxx = float4_swiz_xxxx(_a); + const float4_t yyyy = float4_swiz_yyyy(_a); + const float4_t zzzz = float4_swiz_zzzz(_a); + const float4_t col0 = float4_mul(_b->col[0], xxxx); + const float4_t col1 = float4_mul(_b->col[1], yyyy); + const float4_t col2 = float4_madd(_b->col[2], zzzz, col0); + const float4_t col3 = float4_add(_b->col[3], col1); + const float4_t result = float4_add(col2, col3); + + return result; + } + + BX_FLOAT4_FORCE_INLINE float4_t float4_mul(float4_t _a, const float4x4_t* _b) + { + const float4_t xxxx = float4_swiz_xxxx(_a); + const float4_t yyyy = float4_swiz_yyyy(_a); + const float4_t zzzz = float4_swiz_zzzz(_a); + const float4_t wwww = float4_swiz_wwww(_a); + const float4_t col0 = float4_mul(_b->col[0], xxxx); + const float4_t col1 = float4_mul(_b->col[1], yyyy); + const float4_t col2 = float4_madd(_b->col[2], zzzz, col0); + const float4_t col3 = float4_madd(_b->col[3], wwww, col1); + const float4_t result = float4_add(col2, col3); + + return result; + } + + BX_FLOAT4_INLINE void float4x4_mul(float4x4_t* __restrict _result, const float4x4_t* __restrict _a, const float4x4_t* __restrict _b) + { + _result->col[0] = float4_mul(_a->col[0], _b); + _result->col[1] = float4_mul(_a->col[1], _b); + _result->col[2] = float4_mul(_a->col[2], _b); + _result->col[3] = float4_mul(_a->col[3], _b); + } + + BX_FLOAT4_FORCE_INLINE void float4x4_transpose(float4x4_t* __restrict _result, const float4x4_t* __restrict _mtx) + { + const float4_t aibj = float4_shuf_xAyB(_mtx->col[0], _mtx->col[2]); // aibj + const float4_t emfn = float4_shuf_xAyB(_mtx->col[1], _mtx->col[3]); // emfn + const float4_t ckdl = float4_shuf_zCwD(_mtx->col[0], _mtx->col[2]); // ckdl + const float4_t gohp = float4_shuf_zCwD(_mtx->col[1], _mtx->col[3]); // gohp + _result->col[0] = float4_shuf_xAyB(aibj, emfn); // aeim + _result->col[1] = float4_shuf_zCwD(aibj, emfn); // bfjn + _result->col[2] = float4_shuf_xAyB(ckdl, gohp); // cgko + _result->col[3] = float4_shuf_zCwD(ckdl, gohp); // dhlp + } + + BX_FLOAT4_INLINE void float4x4_inverse(float4x4_t* __restrict _result, const float4x4_t* __restrict _a) + { + const float4_t tmp0 = float4_shuf_xAzC(_a->col[0], _a->col[1]); + const float4_t tmp1 = float4_shuf_xAzC(_a->col[2], _a->col[3]); + const float4_t tmp2 = float4_shuf_yBwD(_a->col[0], _a->col[1]); + const float4_t tmp3 = float4_shuf_yBwD(_a->col[2], _a->col[3]); + const float4_t t0 = float4_shuf_xyAB(tmp0, tmp1); + const float4_t t1 = float4_shuf_xyAB(tmp3, tmp2); + const float4_t t2 = float4_shuf_zwCD(tmp0, tmp1); + const float4_t t3 = float4_shuf_zwCD(tmp3, tmp2); + + const float4_t t23 = float4_mul(t2, t3); + const float4_t t23_yxwz = float4_swiz_yxwz(t23); + const float4_t t23_wzyx = float4_swiz_wzyx(t23); + + float4_t cof0, cof1, cof2, cof3; + + const float4_t zero = float4_zero(); + cof0 = float4_nmsub(t1, t23_yxwz, zero); + cof0 = float4_madd(t1, t23_wzyx, cof0); + + cof1 = float4_nmsub(t0, t23_yxwz, zero); + cof1 = float4_madd(t0, t23_wzyx, cof1); + cof1 = float4_swiz_zwxy(cof1); + + const float4_t t12 = float4_mul(t1, t2); + const float4_t t12_yxwz = float4_swiz_yxwz(t12); + const float4_t t12_wzyx = float4_swiz_wzyx(t12); + + cof0 = float4_madd(t3, t12_yxwz, cof0); + cof0 = float4_nmsub(t3, t12_wzyx, cof0); + + cof3 = float4_mul(t0, t12_yxwz); + cof3 = float4_nmsub(t0, t12_wzyx, cof3); + cof3 = float4_swiz_zwxy(cof3); + + const float4_t t1_zwxy = float4_swiz_zwxy(t1); + const float4_t t2_zwxy = float4_swiz_zwxy(t2); + + const float4_t t13 = float4_mul(t1_zwxy, t3); + const float4_t t13_yxwz = float4_swiz_yxwz(t13); + const float4_t t13_wzyx = float4_swiz_wzyx(t13); + + cof0 = float4_madd(t2_zwxy, t13_yxwz, cof0); + cof0 = float4_nmsub(t2_zwxy, t13_wzyx, cof0); + + cof2 = float4_mul(t0, t13_yxwz); + cof2 = float4_nmsub(t0, t13_wzyx, cof2); + cof2 = float4_swiz_zwxy(cof2); + + const float4_t t01 = float4_mul(t0, t1); + const float4_t t01_yxwz = float4_swiz_yxwz(t01); + const float4_t t01_wzyx = float4_swiz_wzyx(t01); + + cof2 = float4_nmsub(t3, t01_yxwz, cof2); + cof2 = float4_madd(t3, t01_wzyx, cof2); + + cof3 = float4_madd(t2_zwxy, t01_yxwz, cof3); + cof3 = float4_nmsub(t2_zwxy, t01_wzyx, cof3); + + const float4_t t03 = float4_mul(t0, t3); + const float4_t t03_yxwz = float4_swiz_yxwz(t03); + const float4_t t03_wzyx = float4_swiz_wzyx(t03); + + cof1 = float4_nmsub(t2_zwxy, t03_yxwz, cof1); + cof1 = float4_madd(t2_zwxy, t03_wzyx, cof1); + + cof2 = float4_madd(t1, t03_yxwz, cof2); + cof2 = float4_nmsub(t1, t03_wzyx, cof2); + + const float4_t t02 = float4_mul(t0, t2_zwxy); + const float4_t t02_yxwz = float4_swiz_yxwz(t02); + const float4_t t02_wzyx = float4_swiz_wzyx(t02); + + cof1 = float4_madd(t3, t02_yxwz, cof1); + cof1 = float4_nmsub(t3, t02_wzyx, cof1); + + cof3 = float4_nmsub(t1, t02_yxwz, cof3); + cof3 = float4_madd(t1, t02_wzyx, cof3); + + const float4_t det = float4_dot(t0, cof0); + const float4_t invdet = float4_rcp(det); + + _result->col[0] = float4_mul(cof0, invdet); + _result->col[1] = float4_mul(cof1, invdet); + _result->col[2] = float4_mul(cof2, invdet); + _result->col[3] = float4_mul(cof3, invdet); + } + +} // namespace bx + +#endif // BX_FLOAT4X4_H_HEADER_GUARD diff --git a/deps/include/bx/foreach.h b/deps/include/bx/foreach.h new file mode 100644 index 0000000..b51aa23 --- /dev/null +++ b/deps/include/bx/foreach.h @@ -0,0 +1,71 @@ +/* + * Copyright 2010-2015 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#ifndef BX_FOREACH_H_HEADER_GUARD +#define BX_FOREACH_H_HEADER_GUARD + +#include "bx.h" + +namespace bx +{ + namespace foreach_ns + { + struct ContainerBase + { + }; + + template + class Container : public ContainerBase + { + public: + inline Container(const Ty& _container) + : m_container(_container) + , m_break(0) + , m_it( _container.begin() ) + , m_itEnd( _container.end() ) + { + } + + inline bool condition() const + { + return (!m_break++ && m_it != m_itEnd); + } + + const Ty& m_container; + mutable int m_break; + mutable typename Ty::const_iterator m_it; + mutable typename Ty::const_iterator m_itEnd; + }; + + template + inline Ty* pointer(const Ty&) + { + return 0; + } + + template + inline Container containerNew(const Ty& _container) + { + return Container(_container); + } + + template + inline const Container* container(const ContainerBase* _base, const Ty*) + { + return static_cast*>(_base); + } + } // namespace foreach_ns + +#define foreach(_variable, _container) \ + for (const bx::foreach_ns::ContainerBase &__temp_container__ = bx::foreach_ns::containerNew(_container); \ + bx::foreach_ns::container(&__temp_container__, true ? 0 : bx::foreach_ns::pointer(_container) )->condition(); \ + ++bx::foreach_ns::container(&__temp_container__, true ? 0 : bx::foreach_ns::pointer(_container) )->m_it) \ + for (_variable = *container(&__temp_container__, true ? 0 : bx::foreach_ns::pointer(_container) )->m_it; \ + bx::foreach_ns::container(&__temp_container__, true ? 0 : bx::foreach_ns::pointer(_container) )->m_break; \ + --bx::foreach_ns::container(&__temp_container__, true ? 0 : bx::foreach_ns::pointer(_container) )->m_break) + +} // namespace bx + +#endif // BX_FOREACH_H_HEADER_GUARD diff --git a/deps/include/bx/fpumath.h b/deps/include/bx/fpumath.h new file mode 100644 index 0000000..0aa92c8 --- /dev/null +++ b/deps/include/bx/fpumath.h @@ -0,0 +1,976 @@ +/* + * Copyright 2011-2015 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +// FPU math lib + +#ifndef BX_FPU_MATH_H_HEADER_GUARD +#define BX_FPU_MATH_H_HEADER_GUARD + +#include "bx.h" +#include +#include + +namespace bx +{ + static const float pi = 3.14159265358979323846f; + static const float invPi = 1.0f/3.14159265358979323846f; + static const float piHalf = 1.57079632679489661923f; + static const float sqrt2 = 1.41421356237309504880f; + + inline float toRad(float _deg) + { + return _deg * pi / 180.0f; + } + + inline float toDeg(float _rad) + { + return _rad * 180.0f / pi; + } + + inline float fround(float _f) + { + return floorf(_f + 0.5f); + } + + inline float fmin(float _a, float _b) + { + return _a < _b ? _a : _b; + } + + inline float fmax(float _a, float _b) + { + return _a > _b ? _a : _b; + } + + inline float fmin3(float _a, float _b, float _c) + { + return fmin(_a, fmin(_b, _c) ); + } + + inline float fmax3(float _a, float _b, float _c) + { + return fmax(_a, fmax(_b, _c) ); + } + + inline float fclamp(float _a, float _min, float _max) + { + return fmin(fmax(_a, _min), _max); + } + + inline float fsaturate(float _a) + { + return fclamp(_a, 0.0f, 1.0f); + } + + inline float flerp(float _a, float _b, float _t) + { + return _a + (_b - _a) * _t; + } + + inline float fsign(float _a) + { + return _a < 0.0f ? -1.0f : 1.0f; + } + + inline float fstep(float _edge, float _a) + { + return _a < _edge ? 0.0f : 1.0f; + } + + inline float fpulse(float _a, float _start, float _end) + { + return fstep(_a, _start) - fstep(_a, _end); + } + + inline float fabsolute(float _a) + { + return fabsf(_a); + } + + inline float fsqrt(float _a) + { + return sqrtf(_a); + } + + inline float ffract(float _a) + { + return _a - floorf(_a); + } + + inline bool fequal(float _a, float _b, float _epsilon) + { + return fabsolute(_a - _b) <= _epsilon; + } + + inline bool fequal(const float* __restrict _a, const float* __restrict _b, uint32_t _num, float _epsilon) + { + bool equal = fequal(_a[0], _b[0], _epsilon); + for (uint32_t ii = 1; equal && ii < _num; ++ii) + { + equal = fequal(_a[ii], _b[ii], _epsilon); + } + return equal; + } + + inline float fwrap(float _a, float _wrap) + { + const float mod = fmodf(_a, _wrap); + const float result = mod < 0.0f ? _wrap + mod : mod; + return result; + } + + // References: + // - Bias And Gain Are Your Friend + // http://blog.demofox.org/2012/09/24/bias-and-gain-are-your-friend/ + // - http://demofox.org/biasgain.html + inline float fbias(float _time, float _bias) + { + return _time / ( ( (1.0f/_bias - 2.0f)*(1.0f - _time) ) + 1.0f); + } + + inline float fgain(float _time, float _gain) + { + if (_time < 0.5f) + { + return fbias(_time * 2.0f, _gain) * 0.5f; + } + + return fbias(_time * 2.0f - 1.0f, 1.0f - _gain) * 0.5f + 0.5f; + } + + inline void vec3Move(float* __restrict _result, const float* __restrict _a) + { + _result[0] = _a[0]; + _result[1] = _a[1]; + _result[2] = _a[2]; + } + + inline void vec3Abs(float* __restrict _result, const float* __restrict _a) + { + _result[0] = fabsolute(_a[0]); + _result[1] = fabsolute(_a[1]); + _result[2] = fabsolute(_a[2]); + } + + inline void vec3Neg(float* __restrict _result, const float* __restrict _a) + { + _result[0] = -_a[0]; + _result[1] = -_a[1]; + _result[2] = -_a[2]; + } + + inline void vec3Add(float* __restrict _result, const float* __restrict _a, const float* __restrict _b) + { + _result[0] = _a[0] + _b[0]; + _result[1] = _a[1] + _b[1]; + _result[2] = _a[2] + _b[2]; + } + + inline void vec3Sub(float* __restrict _result, const float* __restrict _a, const float* __restrict _b) + { + _result[0] = _a[0] - _b[0]; + _result[1] = _a[1] - _b[1]; + _result[2] = _a[2] - _b[2]; + } + + inline void vec3Mul(float* __restrict _result, const float* __restrict _a, const float* __restrict _b) + { + _result[0] = _a[0] * _b[0]; + _result[1] = _a[1] * _b[1]; + _result[2] = _a[2] * _b[2]; + } + + inline void vec3Mul(float* __restrict _result, const float* __restrict _a, float _b) + { + _result[0] = _a[0] * _b; + _result[1] = _a[1] * _b; + _result[2] = _a[2] * _b; + } + + inline float vec3Dot(const float* __restrict _a, const float* __restrict _b) + { + return _a[0]*_b[0] + _a[1]*_b[1] + _a[2]*_b[2]; + } + + inline void vec3Cross(float* __restrict _result, const float* __restrict _a, const float* __restrict _b) + { + _result[0] = _a[1]*_b[2] - _a[2]*_b[1]; + _result[1] = _a[2]*_b[0] - _a[0]*_b[2]; + _result[2] = _a[0]*_b[1] - _a[1]*_b[0]; + } + + inline float vec3Length(const float* _a) + { + return fsqrt(vec3Dot(_a, _a) ); + } + + inline float vec3Norm(float* __restrict _result, const float* __restrict _a) + { + const float len = vec3Length(_a); + const float invLen = 1.0f/len; + _result[0] = _a[0] * invLen; + _result[1] = _a[1] * invLen; + _result[2] = _a[2] * invLen; + return len; + } + + inline void quatIdentity(float* _result) + { + _result[0] = 0.0f; + _result[1] = 0.0f; + _result[2] = 0.0f; + _result[3] = 1.0f; + } + + inline void quatMulXYZ(float* __restrict _result, const float* __restrict _qa, const float* __restrict _qb) + { + const float ax = _qa[0]; + const float ay = _qa[1]; + const float az = _qa[2]; + const float aw = _qa[3]; + + const float bx = _qb[0]; + const float by = _qb[1]; + const float bz = _qb[2]; + const float bw = _qb[3]; + + _result[0] = aw * bx + ax * bw + ay * bz - az * by; + _result[1] = aw * by - ax * bz + ay * bw + az * bx; + _result[2] = aw * bz + ax * by - ay * bx + az * bw; + } + + inline void quatMul(float* __restrict _result, const float* __restrict _qa, const float* __restrict _qb) + { + const float ax = _qa[0]; + const float ay = _qa[1]; + const float az = _qa[2]; + const float aw = _qa[3]; + + const float bx = _qb[0]; + const float by = _qb[1]; + const float bz = _qb[2]; + const float bw = _qb[3]; + + _result[0] = aw * bx + ax * bw + ay * bz - az * by; + _result[1] = aw * by - ax * bz + ay * bw + az * bx; + _result[2] = aw * bz + ax * by - ay * bx + az * bw; + _result[3] = aw * bw - ax * bx - ay * by - az * bz; + } + + inline void quatInvert(float* __restrict _result, const float* __restrict _quat) + { + _result[0] = -_quat[0]; + _result[1] = -_quat[1]; + _result[2] = -_quat[2]; + _result[3] = _quat[3]; + } + + inline void quatToEuler(float* __restrict _result, const float* __restrict _quat) + { + const float x = _quat[0]; + const float y = _quat[1]; + const float z = _quat[2]; + const float w = _quat[3]; + + const float yy = y * y; + const float zz = z * z; + + const float xx = x * x; + _result[0] = atan2f(2.0f * (x * w - y * z), 1.0f - 2.0f * (xx + zz) ); + _result[1] = atan2f(2.0f * (y * w + x * z), 1.0f - 2.0f * (yy + zz) ); + _result[2] = asinf (2.0f * (x * y + z * w) ); + } + + inline void quatRotateX(float* _result, float _ax) + { + const float hx = _ax * 0.5f; + const float cx = cosf(hx); + const float sx = sinf(hx); + _result[0] = sx; + _result[1] = 0.0f; + _result[2] = 0.0f; + _result[3] = cx; + } + + inline void quatRotateY(float* _result, float _ay) + { + const float hy = _ay * 0.5f; + const float cy = cosf(hy); + const float sy = sinf(hy); + _result[0] = 0.0f; + _result[1] = sy; + _result[2] = 0.0f; + _result[3] = cy; + } + + inline void quatRotateZ(float* _result, float _az) + { + const float hz = _az * 0.5f; + const float cz = cosf(hz); + const float sz = sinf(hz); + _result[0] = 0.0f; + _result[1] = 0.0f; + _result[2] = sz; + _result[3] = cz; + } + + inline void vec3MulQuat(float* __restrict _result, const float* __restrict _vec, const float* __restrict _quat) + { + float tmp0[4]; + quatInvert(tmp0, _quat); + + float qv[4]; + qv[0] = _vec[0]; + qv[1] = _vec[1]; + qv[2] = _vec[2]; + qv[3] = 0.0f; + + float tmp1[4]; + quatMul(tmp1, tmp0, qv); + + quatMulXYZ(_result, tmp1, _quat); + } + + inline void mtxIdentity(float* _result) + { + memset(_result, 0, sizeof(float)*16); + _result[0] = _result[5] = _result[10] = _result[15] = 1.0f; + } + + inline void mtxTranslate(float* _result, float _tx, float _ty, float _tz) + { + mtxIdentity(_result); + _result[12] = _tx; + _result[13] = _ty; + _result[14] = _tz; + } + + inline void mtxScale(float* _result, float _sx, float _sy, float _sz) + { + memset(_result, 0, sizeof(float) * 16); + _result[0] = _sx; + _result[5] = _sy; + _result[10] = _sz; + _result[15] = 1.0f; + } + + inline void mtxQuat(float* __restrict _result, const float* __restrict _quat) + { + const float x = _quat[0]; + const float y = _quat[1]; + const float z = _quat[2]; + const float w = _quat[3]; + + const float x2 = x + x; + const float y2 = y + y; + const float z2 = z + z; + const float x2x = x2 * x; + const float x2y = x2 * y; + const float x2z = x2 * z; + const float x2w = x2 * w; + const float y2y = y2 * y; + const float y2z = y2 * z; + const float y2w = y2 * w; + const float z2z = z2 * z; + const float z2w = z2 * w; + + _result[ 0] = 1.0f - (y2y + z2z); + _result[ 1] = x2y - z2w; + _result[ 2] = x2z + y2w; + _result[ 3] = 0.0f; + + _result[ 4] = x2y + z2w; + _result[ 5] = 1.0f - (x2x + z2z); + _result[ 6] = y2z - x2w; + _result[ 7] = 0.0f; + + _result[ 8] = x2z - y2w; + _result[ 9] = y2z + x2w; + _result[10] = 1.0f - (x2x + y2y); + _result[11] = 0.0f; + + _result[12] = 0.0f; + _result[13] = 0.0f; + _result[14] = 0.0f; + _result[15] = 1.0f; + } + + inline void mtxQuatTranslation(float* __restrict _result, const float* __restrict _quat, const float* __restrict _translation) + { + mtxQuat(_result, _quat); + _result[12] = -(_result[0]*_translation[0] + _result[4]*_translation[1] + _result[ 8]*_translation[2]); + _result[13] = -(_result[1]*_translation[0] + _result[5]*_translation[1] + _result[ 9]*_translation[2]); + _result[14] = -(_result[2]*_translation[0] + _result[6]*_translation[1] + _result[10]*_translation[2]); + } + + inline void mtxQuatTranslationHMD(float* __restrict _result, const float* __restrict _quat, const float* __restrict _translation) + { + float quat[4]; + quat[0] = -_quat[0]; + quat[1] = -_quat[1]; + quat[2] = _quat[2]; + quat[3] = _quat[3]; + mtxQuatTranslation(_result, quat, _translation); + } + + inline void mtxLookAt(float* __restrict _result, const float* __restrict _eye, const float* __restrict _at, const float* __restrict _up = NULL) + { + float tmp[4]; + vec3Sub(tmp, _at, _eye); + + float view[4]; + vec3Norm(view, tmp); + + float up[3] = { 0.0f, 1.0f, 0.0f }; + if (NULL != _up) + { + up[0] = _up[0]; + up[1] = _up[1]; + up[2] = _up[2]; + } + vec3Cross(tmp, up, view); + + float right[4]; + vec3Norm(right, tmp); + + vec3Cross(up, view, right); + + memset(_result, 0, sizeof(float)*16); + _result[ 0] = right[0]; + _result[ 1] = up[0]; + _result[ 2] = view[0]; + + _result[ 4] = right[1]; + _result[ 5] = up[1]; + _result[ 6] = view[1]; + + _result[ 8] = right[2]; + _result[ 9] = up[2]; + _result[10] = view[2]; + + _result[12] = -vec3Dot(right, _eye); + _result[13] = -vec3Dot(up, _eye); + _result[14] = -vec3Dot(view, _eye); + _result[15] = 1.0f; + } + + inline void mtxProjXYWH(float* _result, float _x, float _y, float _width, float _height, float _near, float _far, bool _oglNdc = false) + { + const float diff = _far-_near; + const float aa = _oglNdc ? (_far+_near)/diff : _far/diff; + const float bb = _oglNdc ? -(2.0f*_far*_near)/diff : -_near*aa; + + memset(_result, 0, sizeof(float)*16); + _result[ 0] = _width; + _result[ 5] = _height; + _result[ 8] = _x; + _result[ 9] = -_y; + _result[10] = aa; + _result[11] = 1.0f; + _result[14] = bb; + } + + inline void mtxProj(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, float _far, bool _oglNdc = false) + { + const float width = 2.0f / (_lt + _rt); + const float height = 2.0f / (_ut + _dt); + const float xx = (_lt - _rt) * width * 0.5f; + const float yy = (_ut - _dt) * height * 0.5f; + mtxProjXYWH(_result, xx, yy, width, height, _near, _far, _oglNdc); + } + + inline void mtxProj(float* _result, const float _fov[4], float _near, float _far, bool _oglNdc = false) + { + mtxProj(_result, _fov[0], _fov[1], _fov[2], _fov[3], _near, _far, _oglNdc); + } + + inline void mtxProj(float* _result, float _fovy, float _aspect, float _near, float _far, bool _oglNdc = false) + { + const float height = 1.0f/tanf(toRad(_fovy)*0.5f); + const float width = height * 1.0f/_aspect; + mtxProjXYWH(_result, 0.0f, 0.0f, width, height, _near, _far, _oglNdc); + } + + inline void mtxOrtho(float* _result, float _left, float _right, float _bottom, float _top, float _near, float _far, float _offset = 0.0f) + { + const float aa = 2.0f/(_right - _left); + const float bb = 2.0f/(_top - _bottom); + const float cc = 1.0f/(_far - _near); + const float dd = (_left + _right)/(_left - _right); + const float ee = (_top + _bottom)/(_bottom - _top); + const float ff = _near / (_near - _far); + + memset(_result, 0, sizeof(float)*16); + _result[ 0] = aa; + _result[ 5] = bb; + _result[10] = cc; + _result[12] = dd + _offset; + _result[13] = ee; + _result[14] = ff; + _result[15] = 1.0f; + } + + inline void mtxRotateX(float* _result, float _ax) + { + const float sx = sinf(_ax); + const float cx = cosf(_ax); + + memset(_result, 0, sizeof(float)*16); + _result[ 0] = 1.0f; + _result[ 5] = cx; + _result[ 6] = -sx; + _result[ 9] = sx; + _result[10] = cx; + _result[15] = 1.0f; + } + + inline void mtxRotateY(float* _result, float _ay) + { + const float sy = sinf(_ay); + const float cy = cosf(_ay); + + memset(_result, 0, sizeof(float)*16); + _result[ 0] = cy; + _result[ 2] = sy; + _result[ 5] = 1.0f; + _result[ 8] = -sy; + _result[10] = cy; + _result[15] = 1.0f; + } + + inline void mtxRotateZ(float* _result, float _az) + { + const float sz = sinf(_az); + const float cz = cosf(_az); + + memset(_result, 0, sizeof(float)*16); + _result[ 0] = cz; + _result[ 1] = -sz; + _result[ 4] = sz; + _result[ 5] = cz; + _result[10] = 1.0f; + _result[15] = 1.0f; + } + + inline void mtxRotateXY(float* _result, float _ax, float _ay) + { + const float sx = sinf(_ax); + const float cx = cosf(_ax); + const float sy = sinf(_ay); + const float cy = cosf(_ay); + + memset(_result, 0, sizeof(float)*16); + _result[ 0] = cy; + _result[ 2] = sy; + _result[ 4] = sx*sy; + _result[ 5] = cx; + _result[ 6] = -sx*cy; + _result[ 8] = -cx*sy; + _result[ 9] = sx; + _result[10] = cx*cy; + _result[15] = 1.0f; + } + + inline void mtxRotateXYZ(float* _result, float _ax, float _ay, float _az) + { + const float sx = sinf(_ax); + const float cx = cosf(_ax); + const float sy = sinf(_ay); + const float cy = cosf(_ay); + const float sz = sinf(_az); + const float cz = cosf(_az); + + memset(_result, 0, sizeof(float)*16); + _result[ 0] = cy*cz; + _result[ 1] = -cy*sz; + _result[ 2] = sy; + _result[ 4] = cz*sx*sy + cx*sz; + _result[ 5] = cx*cz - sx*sy*sz; + _result[ 6] = -cy*sx; + _result[ 8] = -cx*cz*sy + sx*sz; + _result[ 9] = cz*sx + cx*sy*sz; + _result[10] = cx*cy; + _result[15] = 1.0f; + } + + inline void mtxRotateZYX(float* _result, float _ax, float _ay, float _az) + { + const float sx = sinf(_ax); + const float cx = cosf(_ax); + const float sy = sinf(_ay); + const float cy = cosf(_ay); + const float sz = sinf(_az); + const float cz = cosf(_az); + + memset(_result, 0, sizeof(float)*16); + _result[ 0] = cy*cz; + _result[ 1] = cz*sx*sy-cx*sz; + _result[ 2] = cx*cz*sy+sx*sz; + _result[ 4] = cy*sz; + _result[ 5] = cx*cz + sx*sy*sz; + _result[ 6] = -cz*sx + cx*sy*sz; + _result[ 8] = -sy; + _result[ 9] = cy*sx; + _result[10] = cx*cy; + _result[15] = 1.0f; + }; + + inline void mtxSRT(float* _result, float _sx, float _sy, float _sz, float _ax, float _ay, float _az, float _tx, float _ty, float _tz) + { + const float sx = sinf(_ax); + const float cx = cosf(_ax); + const float sy = sinf(_ay); + const float cy = cosf(_ay); + const float sz = sinf(_az); + const float cz = cosf(_az); + + const float sxsz = sx*sz; + const float cycz = cy*cz; + + _result[ 0] = _sx * (cycz - sxsz*sy); + _result[ 1] = _sx * -cx*sz; + _result[ 2] = _sx * (cz*sy + cy*sxsz); + _result[ 3] = 0.0f; + + _result[ 4] = _sy * (cz*sx*sy + cy*sz); + _result[ 5] = _sy * cx*cz; + _result[ 6] = _sy * (sy*sz -cycz*sx); + _result[ 7] = 0.0f; + + _result[ 8] = _sz * -cx*sy; + _result[ 9] = _sz * sx; + _result[10] = _sz * cx*cy; + _result[11] = 0.0f; + + _result[12] = _tx; + _result[13] = _ty; + _result[14] = _tz; + _result[15] = 1.0f; + } + + inline void vec3MulMtx(float* __restrict _result, const float* __restrict _vec, const float* __restrict _mat) + { + _result[0] = _vec[0] * _mat[ 0] + _vec[1] * _mat[4] + _vec[2] * _mat[ 8] + _mat[12]; + _result[1] = _vec[0] * _mat[ 1] + _vec[1] * _mat[5] + _vec[2] * _mat[ 9] + _mat[13]; + _result[2] = _vec[0] * _mat[ 2] + _vec[1] * _mat[6] + _vec[2] * _mat[10] + _mat[14]; + } + + inline void vec3MulMtxH(float* __restrict _result, const float* __restrict _vec, const float* __restrict _mat) + { + float xx = _vec[0] * _mat[ 0] + _vec[1] * _mat[4] + _vec[2] * _mat[ 8] + _mat[12]; + float yy = _vec[0] * _mat[ 1] + _vec[1] * _mat[5] + _vec[2] * _mat[ 9] + _mat[13]; + float zz = _vec[0] * _mat[ 2] + _vec[1] * _mat[6] + _vec[2] * _mat[10] + _mat[14]; + float ww = _vec[0] * _mat[ 3] + _vec[1] * _mat[7] + _vec[2] * _mat[11] + _mat[15]; + float invW = fsign(ww)/ww; + _result[0] = xx*invW; + _result[1] = yy*invW; + _result[2] = zz*invW; + } + + inline void vec4MulMtx(float* __restrict _result, const float* __restrict _vec, const float* __restrict _mat) + { + _result[0] = _vec[0] * _mat[ 0] + _vec[1] * _mat[4] + _vec[2] * _mat[ 8] + _vec[3] * _mat[12]; + _result[1] = _vec[0] * _mat[ 1] + _vec[1] * _mat[5] + _vec[2] * _mat[ 9] + _vec[3] * _mat[13]; + _result[2] = _vec[0] * _mat[ 2] + _vec[1] * _mat[6] + _vec[2] * _mat[10] + _vec[3] * _mat[14]; + _result[3] = _vec[0] * _mat[ 3] + _vec[1] * _mat[7] + _vec[2] * _mat[11] + _vec[3] * _mat[15]; + } + + inline void mtxMul(float* __restrict _result, const float* __restrict _a, const float* __restrict _b) + { + vec4MulMtx(&_result[ 0], &_a[ 0], _b); + vec4MulMtx(&_result[ 4], &_a[ 4], _b); + vec4MulMtx(&_result[ 8], &_a[ 8], _b); + vec4MulMtx(&_result[12], &_a[12], _b); + } + + inline void mtxTranspose(float* __restrict _result, const float* __restrict _a) + { + _result[ 0] = _a[ 0]; + _result[ 4] = _a[ 1]; + _result[ 8] = _a[ 2]; + _result[12] = _a[ 3]; + _result[ 1] = _a[ 4]; + _result[ 5] = _a[ 5]; + _result[ 9] = _a[ 6]; + _result[13] = _a[ 7]; + _result[ 2] = _a[ 8]; + _result[ 6] = _a[ 9]; + _result[10] = _a[10]; + _result[14] = _a[11]; + _result[ 3] = _a[12]; + _result[ 7] = _a[13]; + _result[11] = _a[14]; + _result[15] = _a[15]; + } + + inline void mtx3Inverse(float* __restrict _result, const float* __restrict _a) + { + float xx = _a[0]; + float xy = _a[1]; + float xz = _a[2]; + float yx = _a[3]; + float yy = _a[4]; + float yz = _a[5]; + float zx = _a[6]; + float zy = _a[7]; + float zz = _a[8]; + + float det = 0.0f; + det += xx * (yy*zz - yz*zy); + det -= xy * (yx*zz - yz*zx); + det += xz * (yx*zy - yy*zx); + + float invDet = 1.0f/det; + + _result[0] = +(yy*zz - yz*zy) * invDet; + _result[1] = -(xy*zz - xz*zy) * invDet; + _result[2] = +(xy*yz - xz*yy) * invDet; + + _result[3] = -(yx*zz - yz*zx) * invDet; + _result[4] = +(xx*zz - xz*zx) * invDet; + _result[5] = -(xx*yz - xz*yx) * invDet; + + _result[6] = +(yx*zy - yy*zx) * invDet; + _result[7] = -(xx*zy - xy*zx) * invDet; + _result[8] = +(xx*yy - xy*yx) * invDet; + } + + inline void mtxInverse(float* __restrict _result, const float* __restrict _a) + { + float xx = _a[ 0]; + float xy = _a[ 1]; + float xz = _a[ 2]; + float xw = _a[ 3]; + float yx = _a[ 4]; + float yy = _a[ 5]; + float yz = _a[ 6]; + float yw = _a[ 7]; + float zx = _a[ 8]; + float zy = _a[ 9]; + float zz = _a[10]; + float zw = _a[11]; + float wx = _a[12]; + float wy = _a[13]; + float wz = _a[14]; + float ww = _a[15]; + + float det = 0.0f; + det += xx * (yy*(zz*ww - zw*wz) - yz*(zy*ww - zw*wy) + yw*(zy*wz - zz*wy) ); + det -= xy * (yx*(zz*ww - zw*wz) - yz*(zx*ww - zw*wx) + yw*(zx*wz - zz*wx) ); + det += xz * (yx*(zy*ww - zw*wy) - yy*(zx*ww - zw*wx) + yw*(zx*wy - zy*wx) ); + det -= xw * (yx*(zy*wz - zz*wy) - yy*(zx*wz - zz*wx) + yz*(zx*wy - zy*wx) ); + + float invDet = 1.0f/det; + + _result[ 0] = +(yy*(zz*ww - wz*zw) - yz*(zy*ww - wy*zw) + yw*(zy*wz - wy*zz) ) * invDet; + _result[ 1] = -(xy*(zz*ww - wz*zw) - xz*(zy*ww - wy*zw) + xw*(zy*wz - wy*zz) ) * invDet; + _result[ 2] = +(xy*(yz*ww - wz*yw) - xz*(yy*ww - wy*yw) + xw*(yy*wz - wy*yz) ) * invDet; + _result[ 3] = -(xy*(yz*zw - zz*yw) - xz*(yy*zw - zy*yw) + xw*(yy*zz - zy*yz) ) * invDet; + + _result[ 4] = -(yx*(zz*ww - wz*zw) - yz*(zx*ww - wx*zw) + yw*(zx*wz - wx*zz) ) * invDet; + _result[ 5] = +(xx*(zz*ww - wz*zw) - xz*(zx*ww - wx*zw) + xw*(zx*wz - wx*zz) ) * invDet; + _result[ 6] = -(xx*(yz*ww - wz*yw) - xz*(yx*ww - wx*yw) + xw*(yx*wz - wx*yz) ) * invDet; + _result[ 7] = +(xx*(yz*zw - zz*yw) - xz*(yx*zw - zx*yw) + xw*(yx*zz - zx*yz) ) * invDet; + + _result[ 8] = +(yx*(zy*ww - wy*zw) - yy*(zx*ww - wx*zw) + yw*(zx*wy - wx*zy) ) * invDet; + _result[ 9] = -(xx*(zy*ww - wy*zw) - xy*(zx*ww - wx*zw) + xw*(zx*wy - wx*zy) ) * invDet; + _result[10] = +(xx*(yy*ww - wy*yw) - xy*(yx*ww - wx*yw) + xw*(yx*wy - wx*yy) ) * invDet; + _result[11] = -(xx*(yy*zw - zy*yw) - xy*(yx*zw - zx*yw) + xw*(yx*zy - zx*yy) ) * invDet; + + _result[12] = -(yx*(zy*wz - wy*zz) - yy*(zx*wz - wx*zz) + yz*(zx*wy - wx*zy) ) * invDet; + _result[13] = +(xx*(zy*wz - wy*zz) - xy*(zx*wz - wx*zz) + xz*(zx*wy - wx*zy) ) * invDet; + _result[14] = -(xx*(yy*wz - wy*yz) - xy*(yx*wz - wx*yz) + xz*(yx*wy - wx*yy) ) * invDet; + _result[15] = +(xx*(yy*zz - zy*yz) - xy*(yx*zz - zx*yz) + xz*(yx*zy - zx*yy) ) * invDet; + } + + /// Convert LH to RH projection matrix and vice versa. + inline void mtxProjFlipHandedness(float* __restrict _dst, const float* __restrict _src) + { + _dst[ 0] = -_src[ 0]; + _dst[ 1] = -_src[ 1]; + _dst[ 2] = -_src[ 2]; + _dst[ 3] = -_src[ 3]; + _dst[ 4] = _src[ 4]; + _dst[ 5] = _src[ 5]; + _dst[ 6] = _src[ 6]; + _dst[ 7] = _src[ 7]; + _dst[ 8] = -_src[ 8]; + _dst[ 9] = -_src[ 9]; + _dst[10] = -_src[10]; + _dst[11] = -_src[11]; + _dst[12] = _src[12]; + _dst[13] = _src[13]; + _dst[14] = _src[14]; + _dst[15] = _src[15]; + } + + /// Convert LH to RH view matrix and vice versa. + inline void mtxViewFlipHandedness(float* __restrict _dst, const float* __restrict _src) + { + _dst[ 0] = -_src[ 0]; + _dst[ 1] = _src[ 1]; + _dst[ 2] = -_src[ 2]; + _dst[ 3] = _src[ 3]; + _dst[ 4] = -_src[ 4]; + _dst[ 5] = _src[ 5]; + _dst[ 6] = -_src[ 6]; + _dst[ 7] = _src[ 7]; + _dst[ 8] = -_src[ 8]; + _dst[ 9] = _src[ 9]; + _dst[10] = -_src[10]; + _dst[11] = _src[11]; + _dst[12] = -_src[12]; + _dst[13] = _src[13]; + _dst[14] = -_src[14]; + _dst[15] = _src[15]; + } + + inline void calcNormal(float _result[3], float _va[3], float _vb[3], float _vc[3]) + { + float ba[3]; + vec3Sub(ba, _vb, _va); + + float ca[3]; + vec3Sub(ca, _vc, _va); + + float baxca[3]; + vec3Cross(baxca, ba, ca); + + vec3Norm(_result, baxca); + } + + inline void calcPlane(float _result[4], float _va[3], float _vb[3], float _vc[3]) + { + float normal[3]; + calcNormal(normal, _va, _vb, _vc); + + _result[0] = normal[0]; + _result[1] = normal[1]; + _result[2] = normal[2]; + _result[3] = -vec3Dot(normal, _va); + } + + inline void calcLinearFit2D(float _result[2], const void* _points, uint32_t _stride, uint32_t _numPoints) + { + float sumX = 0.0f; + float sumY = 0.0f; + float sumXX = 0.0f; + float sumXY = 0.0f; + + const uint8_t* ptr = (const uint8_t*)_points; + for (uint32_t ii = 0; ii < _numPoints; ++ii, ptr += _stride) + { + const float* point = (const float*)ptr; + float xx = point[0]; + float yy = point[1]; + sumX += xx; + sumY += yy; + sumXX += xx*xx; + sumXY += xx*yy; + } + + // [ sum(x^2) sum(x) ] [ A ] = [ sum(x*y) ] + // [ sum(x) numPoints ] [ B ] [ sum(y) ] + + float det = (sumXX*_numPoints - sumX*sumX); + float invDet = 1.0f/det; + + _result[0] = (-sumX * sumY + _numPoints * sumXY) * invDet; + _result[1] = (sumXX * sumY - sumX * sumXY) * invDet; + } + + inline void calcLinearFit3D(float _result[3], const void* _points, uint32_t _stride, uint32_t _numPoints) + { + float sumX = 0.0f; + float sumY = 0.0f; + float sumZ = 0.0f; + float sumXX = 0.0f; + float sumXY = 0.0f; + float sumXZ = 0.0f; + float sumYY = 0.0f; + float sumYZ = 0.0f; + + const uint8_t* ptr = (const uint8_t*)_points; + for (uint32_t ii = 0; ii < _numPoints; ++ii, ptr += _stride) + { + const float* point = (const float*)ptr; + float xx = point[0]; + float yy = point[1]; + float zz = point[2]; + + sumX += xx; + sumY += yy; + sumZ += zz; + sumXX += xx*xx; + sumXY += xx*yy; + sumXZ += xx*zz; + sumYY += yy*yy; + sumYZ += yy*zz; + } + + // [ sum(x^2) sum(x*y) sum(x) ] [ A ] [ sum(x*z) ] + // [ sum(x*y) sum(y^2) sum(y) ] [ B ] = [ sum(y*z) ] + // [ sum(x) sum(y) numPoints ] [ C ] [ sum(z) ] + + float mtx[9] = + { + sumXX, sumXY, sumX, + sumXY, sumYY, sumY, + sumX, sumY, float(_numPoints), + }; + float invMtx[9]; + mtx3Inverse(invMtx, mtx); + + _result[0] = invMtx[0]*sumXZ + invMtx[1]*sumYZ + invMtx[2]*sumZ; + _result[1] = invMtx[3]*sumXZ + invMtx[4]*sumYZ + invMtx[5]*sumZ; + _result[2] = invMtx[6]*sumXZ + invMtx[7]*sumYZ + invMtx[8]*sumZ; + } + + inline void rgbToHsv(float _hsv[3], const float _rgb[3]) + { + const float rr = _rgb[0]; + const float gg = _rgb[1]; + const float bb = _rgb[2]; + + const float s0 = fstep(bb, gg); + + const float px = flerp(bb, gg, s0); + const float py = flerp(gg, bb, s0); + const float pz = flerp(-1.0f, 0.0f, s0); + const float pw = flerp(2.0f/3.0f, -1.0f/3.0f, s0); + + const float s1 = fstep(px, rr); + + const float qx = flerp(px, rr, s1); + const float qy = py; + const float qz = flerp(pw, pz, s1); + const float qw = flerp(rr, px, s1); + + const float dd = qx - fmin(qw, qy); + const float ee = 1.0e-10f; + + _hsv[0] = fabsolute(qz + (qw - qy) / (6.0f * dd + ee) ); + _hsv[1] = dd / (qx + ee); + _hsv[2] = qx; + } + + inline void hsvToRgb(float _rgb[3], const float _hsv[3]) + { + const float hh = _hsv[0]; + const float ss = _hsv[1]; + const float vv = _hsv[2]; + + const float px = fabsolute(ffract(hh + 1.0f ) * 6.0f - 3.0f); + const float py = fabsolute(ffract(hh + 2.0f/3.0f) * 6.0f - 3.0f); + const float pz = fabsolute(ffract(hh + 1.0f/3.0f) * 6.0f - 3.0f); + + _rgb[0] = vv * flerp(1.0f, fsaturate(px - 1.0f), ss); + _rgb[1] = vv * flerp(1.0f, fsaturate(py - 1.0f), ss); + _rgb[2] = vv * flerp(1.0f, fsaturate(pz - 1.0f), ss); + } + +} // namespace bx + +#endif // BX_FPU_MATH_H_HEADER_GUARD diff --git a/deps/include/bx/handlealloc.h b/deps/include/bx/handlealloc.h new file mode 100644 index 0000000..332fa1d --- /dev/null +++ b/deps/include/bx/handlealloc.h @@ -0,0 +1,427 @@ +/* + * Copyright 2010-2015 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#ifndef BX_HANDLE_ALLOC_H_HEADER_GUARD +#define BX_HANDLE_ALLOC_H_HEADER_GUARD + +#include "bx.h" +#include "allocator.h" + +namespace bx +{ + class HandleAlloc + { + public: + static const uint16_t invalid = UINT16_MAX; + + HandleAlloc(uint16_t _maxHandles) + : m_numHandles(0) + , m_maxHandles(_maxHandles) + { + reset(); + } + + ~HandleAlloc() + { + } + + const uint16_t* getHandles() const + { + return getDensePtr(); + } + + uint16_t getHandleAt(uint16_t _at) const + { + return getDensePtr()[_at]; + } + + uint16_t getNumHandles() const + { + return m_numHandles; + } + + uint16_t getMaxHandles() const + { + return m_maxHandles; + } + + uint16_t alloc() + { + if (m_numHandles < m_maxHandles) + { + uint16_t index = m_numHandles; + ++m_numHandles; + + uint16_t* dense = getDensePtr(); + uint16_t handle = dense[index]; + uint16_t* sparse = getSparsePtr(); + sparse[handle] = index; + return handle; + } + + return invalid; + } + + bool isValid(uint16_t _handle) const + { + uint16_t* dense = getDensePtr(); + uint16_t* sparse = getSparsePtr(); + uint16_t index = sparse[_handle]; + + return index < m_numHandles + && dense[index] == _handle + ; + } + + void free(uint16_t _handle) + { + uint16_t* dense = getDensePtr(); + uint16_t* sparse = getSparsePtr(); + uint16_t index = sparse[_handle]; + --m_numHandles; + uint16_t temp = dense[m_numHandles]; + dense[m_numHandles] = _handle; + sparse[temp] = index; + dense[index] = temp; + } + + void reset() + { + m_numHandles = 0; + uint16_t* dense = getDensePtr(); + for (uint16_t ii = 0, num = m_maxHandles; ii < num; ++ii) + { + dense[ii] = ii; + } + } + + private: + HandleAlloc(); + + uint16_t* getDensePtr() const + { + uint8_t* ptr = (uint8_t*)reinterpret_cast(this); + return (uint16_t*)&ptr[sizeof(HandleAlloc)]; + } + + uint16_t* getSparsePtr() const + { + return &getDensePtr()[m_maxHandles]; + } + + uint16_t m_numHandles; + uint16_t m_maxHandles; + }; + + inline HandleAlloc* createHandleAlloc(AllocatorI* _allocator, uint16_t _maxHandles) + { + uint8_t* ptr = (uint8_t*)BX_ALLOC(_allocator, sizeof(HandleAlloc) + 2*_maxHandles*sizeof(uint16_t) ); + return ::new (ptr) HandleAlloc(_maxHandles); + } + + inline void destroyHandleAlloc(AllocatorI* _allocator, HandleAlloc* _handleAlloc) + { + _handleAlloc->~HandleAlloc(); + BX_FREE(_allocator, _handleAlloc); + } + + template + class HandleAllocT : public HandleAlloc + { + public: + HandleAllocT() + : HandleAlloc(MaxHandlesT) + { + } + + ~HandleAllocT() + { + } + + private: + uint16_t m_padding[2*MaxHandlesT]; + }; + + template + class HandleListT + { + public: + static const uint16_t invalid = UINT16_MAX; + + HandleListT() + : m_front(invalid) + , m_back(invalid) + { + reset(); + } + + void pushBack(uint16_t _handle) + { + insertAfter(m_back, _handle); + } + + uint16_t popBack() + { + uint16_t last = invalid != m_back + ? m_back + : m_front + ; + + if (invalid != last) + { + remove(last); + } + + return last; + } + + void pushFront(uint16_t _handle) + { + insertBefore(m_front, _handle); + } + + uint16_t popFront() + { + uint16_t front = m_front; + + if (invalid != front) + { + remove(front); + } + + return front; + } + + uint16_t getFront() const + { + return m_front; + } + + uint16_t getBack() const + { + return m_back; + } + + uint16_t getNext(uint16_t _handle) const + { + BX_CHECK(isValid(_handle), "Invalid handle %d!", _handle); + const Link& curr = m_links[_handle]; + return curr.m_next; + } + + uint16_t getPrev(uint16_t _handle) const + { + BX_CHECK(isValid(_handle), "Invalid handle %d!", _handle); + const Link& curr = m_links[_handle]; + return curr.m_prev; + } + + void remove(uint16_t _handle) + { + BX_CHECK(isValid(_handle), "Invalid handle %d!", _handle); + Link& curr = m_links[_handle]; + + if (invalid != curr.m_prev) + { + Link& prev = m_links[curr.m_prev]; + prev.m_next = curr.m_next; + } + else + { + m_front = curr.m_next; + } + + if (invalid != curr.m_next) + { + Link& next = m_links[curr.m_next]; + next.m_prev = curr.m_prev; + } + else + { + m_back = curr.m_prev; + } + + curr.m_prev = invalid; + curr.m_next = invalid; + } + + void reset() + { + memset(m_links, 0xff, sizeof(m_links) ); + } + + private: + void insertBefore(int16_t _before, uint16_t _handle) + { + Link& curr = m_links[_handle]; + curr.m_next = _before; + + if (invalid != _before) + { + Link& link = m_links[_before]; + if (invalid != link.m_prev) + { + Link& prev = m_links[link.m_prev]; + prev.m_next = _handle; + } + + curr.m_prev = link.m_prev; + link.m_prev = _handle; + } + + updateFrontBack(_handle); + } + + void insertAfter(uint16_t _after, uint16_t _handle) + { + Link& curr = m_links[_handle]; + curr.m_prev = _after; + + if (invalid != _after) + { + Link& link = m_links[_after]; + if (invalid != link.m_next) + { + Link& next = m_links[link.m_next]; + next.m_prev = _handle; + } + + curr.m_next = link.m_next; + link.m_next = _handle; + } + + updateFrontBack(_handle); + } + + bool isValid(uint16_t _handle) const + { + return _handle < MaxHandlesT; + } + + void updateFrontBack(uint16_t _handle) + { + Link& curr = m_links[_handle]; + + if (invalid == curr.m_prev) + { + m_front = _handle; + } + + if (invalid == curr.m_next) + { + m_back = _handle; + } + } + + uint16_t m_front; + uint16_t m_back; + + struct Link + { + uint16_t m_prev; + uint16_t m_next; + }; + + Link m_links[MaxHandlesT]; + }; + + template + class HandleAllocLruT + { + public: + static const uint16_t invalid = UINT16_MAX; + + HandleAllocLruT() + { + reset(); + } + + ~HandleAllocLruT() + { + } + + const uint16_t* getHandles() const + { + return m_alloc.getHandles(); + } + + uint16_t getHandleAt(uint16_t _at) const + { + return m_alloc.getHandleAt(_at); + } + + uint16_t getNumHandles() const + { + return m_alloc.getNumHandles(); + } + + uint16_t getMaxHandles() const + { + return m_alloc.getMaxHandles(); + } + + uint16_t alloc() + { + uint16_t handle = m_alloc.alloc(); + if (invalid != handle) + { + m_list.pushFront(handle); + } + return handle; + } + + bool isValid(uint16_t _handle) const + { + return m_alloc.isValid(_handle); + } + + void free(uint16_t _handle) + { + BX_CHECK(isValid(_handle), "Invalid handle %d!", _handle); + m_list.remove(_handle); + m_alloc.free(_handle); + } + + void touch(uint16_t _handle) + { + BX_CHECK(isValid(_handle), "Invalid handle %d!", _handle); + m_list.remove(_handle); + m_list.pushFront(_handle); + } + + uint16_t getFront() const + { + return m_list.getFront(); + } + + uint16_t getBack() const + { + return m_list.getBack(); + } + + uint16_t getNext(uint16_t _handle) const + { + return m_list.getNext(_handle); + } + + uint16_t getPrev(uint16_t _handle) const + { + return m_list.getPrev(_handle); + } + + void reset() + { + m_list.reset(); + m_alloc.reset(); + } + + private: + HandleListT m_list; + HandleAllocT m_alloc; + }; + +} // namespace bx + +#endif // BX_HANDLE_ALLOC_H_HEADER_GUARD diff --git a/deps/include/bx/hash.h b/deps/include/bx/hash.h new file mode 100644 index 0000000..d2f1173 --- /dev/null +++ b/deps/include/bx/hash.h @@ -0,0 +1,170 @@ +/* + * Copyright 2010-2015 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#ifndef BX_HASH_H_HEADER_GUARD +#define BX_HASH_H_HEADER_GUARD + +#include "bx.h" + +namespace bx +{ +// MurmurHash2 was written by Austin Appleby, and is placed in the public +// domain. The author hereby disclaims copyright to this source code. + +#define MURMUR_M 0x5bd1e995 +#define MURMUR_R 24 +#define mmix(_h, _k) { _k *= MURMUR_M; _k ^= _k >> MURMUR_R; _k *= MURMUR_M; _h *= MURMUR_M; _h ^= _k; } + + class HashMurmur2A + { + public: + void begin(uint32_t _seed = 0) + { + m_hash = _seed; + m_tail = 0; + m_count = 0; + m_size = 0; + } + + void add(const void* _data, int _len) + { + if (BX_ENABLED(BX_PLATFORM_EMSCRIPTEN) + && BX_UNLIKELY(!isPtrAligned(_data, 4) ) ) + { + addUnaligned(_data, _len); + return; + } + + addAligned(_data, _len); + } + + void addAligned(const void* _data, int _len) + { + const uint8_t* data = (const uint8_t*)_data; + m_size += _len; + + mixTail(data, _len); + + while(_len >= 4) + { + uint32_t kk = *(uint32_t*)data; + + mmix(m_hash, kk); + + data += 4; + _len -= 4; + } + + mixTail(data, _len); + } + + void addUnaligned(const void* _data, int _len) + { + const uint8_t* data = (const uint8_t*)_data; + m_size += _len; + + mixTail(data, _len); + + while(_len >= 4) + { + uint32_t kk; + readUnaligned(data, kk); + + mmix(m_hash, kk); + + data += 4; + _len -= 4; + } + + mixTail(data, _len); + } + + template + void add(Ty _value) + { + add(&_value, sizeof(Ty) ); + } + + uint32_t end() + { + mmix(m_hash, m_tail); + mmix(m_hash, m_size); + + m_hash ^= m_hash >> 13; + m_hash *= MURMUR_M; + m_hash ^= m_hash >> 15; + + return m_hash; + } + + private: + static void readUnaligned(const void* _data, uint32_t& _out) + { + const uint8_t* data = (const uint8_t*)_data; + if (BX_ENABLED(BX_CPU_ENDIAN_LITTLE) ) + { + _out = 0 + | data[0]<<24 + | data[1]<<16 + | data[2]<<8 + | data[3] + ; + } + else + { + _out = 0 + | data[0] + | data[1]<<8 + | data[2]<<16 + | data[3]<<24 + ; + } + } + + void mixTail(const uint8_t*& _data, int& _len) + { + while( _len && ((_len<4) || m_count) ) + { + m_tail |= (*_data++) << (m_count * 8); + + m_count++; + _len--; + + if(m_count == 4) + { + mmix(m_hash, m_tail); + m_tail = 0; + m_count = 0; + } + } + } + + uint32_t m_hash; + uint32_t m_tail; + uint32_t m_count; + uint32_t m_size; + }; + +#undef MURMUR_M +#undef MURMUR_R +#undef mmix + + inline uint32_t hashMurmur2A(const void* _data, uint32_t _size) + { + HashMurmur2A murmur; + murmur.begin(); + murmur.add(_data, (int)_size); + return murmur.end(); + } + + template + inline uint32_t hashMurmur2A(const Ty& _data) + { + return hashMurmur2A(&_data, sizeof(Ty) ); + } + +} // namespace bx + +#endif // BX_HASH_H_HEADER_GUARD diff --git a/deps/include/bx/macros.h b/deps/include/bx/macros.h new file mode 100644 index 0000000..607c8fe --- /dev/null +++ b/deps/include/bx/macros.h @@ -0,0 +1,226 @@ +/* + * Copyright 2010-2015 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#ifndef BX_MACROS_H_HEADER_GUARD +#define BX_MACROS_H_HEADER_GUARD + +#include "bx.h" + +/// +#if BX_COMPILER_MSVC +// 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_ ( +# define BX_VA_ARGS_PASS_2_ ) +#else +# define BX_VA_ARGS_PASS(...) (__VA_ARGS__) +#endif // BX_COMPILER_MSVC + +#define BX_VA_ARGS_COUNT(...) BX_VA_ARGS_COUNT_ BX_VA_ARGS_PASS(__VA_ARGS__, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1) +#define BX_VA_ARGS_COUNT_(_a1, _a2, _a3, _a4, _a5, _a6, _a7, _a8, _a9, _a10, _a11, _a12, _a13, _a14, _a15, _a16, _last, ...) _last + +/// +#define BX_MACRO_DISPATCHER(_func, ...) BX_MACRO_DISPATCHER_1_(_func, BX_VA_ARGS_COUNT(__VA_ARGS__) ) +#define BX_MACRO_DISPATCHER_1_(_func, _argCount) BX_MACRO_DISPATCHER_2_(_func, _argCount) +#define BX_MACRO_DISPATCHER_2_(_func, _argCount) BX_CONCATENATE(_func, _argCount) + +/// +#define BX_MAKEFOURCC(_a, _b, _c, _d) ( ( (uint32_t)(_a) | ( (uint32_t)(_b) << 8) | ( (uint32_t)(_c) << 16) | ( (uint32_t)(_d) << 24) ) ) + +/// +#define BX_STRINGIZE(_x) BX_STRINGIZE_(_x) +#define BX_STRINGIZE_(_x) #_x + +/// +#define BX_CONCATENATE(_x, _y) BX_CONCATENATE_(_x, _y) +#define BX_CONCATENATE_(_x, _y) _x ## _y + +/// +#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 BX_COMPILER_GCC || BX_COMPILER_CLANG +# define BX_ALIGN_DECL(_align, _decl) _decl __attribute__( (aligned(_align) ) ) +# define BX_ALLOW_UNUSED __attribute__( (unused) ) +# define BX_FORCE_INLINE __extension__ static __inline __attribute__( (__always_inline__) ) +# define BX_FUNCTION __PRETTY_FUNCTION__ +# define BX_LIKELY(_x) __builtin_expect(!!(_x), 1) +# define BX_UNLIKELY(_x) __builtin_expect(!!(_x), 0) +# define BX_NO_INLINE __attribute__( (noinline) ) +# define BX_NO_RETURN __attribute__( (noreturn) ) +# define BX_NO_VTABLE +# define BX_OVERRIDE +# define BX_PRINTF_ARGS(_format, _args) __attribute__ ( (format(__printf__, _format, _args) ) ) +# if BX_COMPILER_CLANG && (BX_PLATFORM_OSX || BX_PLATFORM_IOS) +# define BX_THREAD /* not supported right now */ +# else +# if (__GNUC__ == 4) && (__GNUC_MINOR__ <= 2) +# define BX_THREAD /* not supported right now */ +# else +# define BX_THREAD __thread +# endif // __GNUC__ <= 4.2 +# endif // BX_COMPILER_CLANG +# define BX_ATTRIBUTE(_x) __attribute__( (_x) ) +# if BX_COMPILER_MSVC_COMPATIBLE +# define __stdcall +# endif // BX_COMPILER_MSVC_COMPATIBLE +#elif BX_COMPILER_MSVC +# define BX_ALIGN_DECL(_align, _decl) __declspec(align(_align) ) _decl +# define BX_ALLOW_UNUSED +# define BX_FORCE_INLINE __forceinline +# define BX_FUNCTION __FUNCTION__ +# define BX_LIKELY(_x) (_x) +# define BX_UNLIKELY(_x) (_x) +# define BX_NO_INLINE __declspec(noinline) +# define BX_NO_RETURN +# define BX_NO_VTABLE __declspec(novtable) +# define BX_OVERRIDE override +# define BX_PRINTF_ARGS(_format, _args) +# define BX_THREAD __declspec(thread) +# define BX_ATTRIBUTE(_x) +#else +# error "Unknown BX_COMPILER_?" +#endif + +#if defined(__has_extension) +# define BX_CLANG_HAS_EXTENSION(_x) __has_extension(_x) +#else +# define BX_CLANG_HAS_EXTENSION(_x) 0 +#endif // defined(__has_extension) + +// #define BX_STATIC_ASSERT(_condition, ...) static_assert(_condition, "" __VA_ARGS__) +#define BX_STATIC_ASSERT(_condition, ...) typedef char BX_CONCATENATE(BX_STATIC_ASSERT_, __LINE__)[1][(_condition)] BX_ATTRIBUTE(unused) + +/// +#define BX_ALIGN_DECL_16(_decl) BX_ALIGN_DECL(16, _decl) +#define BX_ALIGN_DECL_256(_decl) BX_ALIGN_DECL(256, _decl) +#define BX_ALIGN_DECL_CACHE_LINE(_decl) BX_ALIGN_DECL(BX_CACHE_LINE_SIZE, _decl) + +/// +#define BX_MACRO_BLOCK_BEGIN for(;;) { +#define BX_MACRO_BLOCK_END break; } +#define BX_NOOP(...) BX_MACRO_BLOCK_BEGIN BX_MACRO_BLOCK_END + +/// +#define BX_UNUSED_1(_a1) BX_MACRO_BLOCK_BEGIN (void)(true ? (void)0 : ( (void)(_a1) ) ); BX_MACRO_BLOCK_END +#define BX_UNUSED_2(_a1, _a2) BX_UNUSED_1(_a1); BX_UNUSED_1(_a2) +#define BX_UNUSED_3(_a1, _a2, _a3) BX_UNUSED_2(_a1, _a2); BX_UNUSED_1(_a3) +#define BX_UNUSED_4(_a1, _a2, _a3, _a4) BX_UNUSED_3(_a1, _a2, _a3); BX_UNUSED_1(_a4) +#define BX_UNUSED_5(_a1, _a2, _a3, _a4, _a5) BX_UNUSED_4(_a1, _a2, _a3, _a4); BX_UNUSED_1(_a5) +#define BX_UNUSED_6(_a1, _a2, _a3, _a4, _a5, _a6) BX_UNUSED_5(_a1, _a2, _a3, _a4, _a5); BX_UNUSED_1(_a6) +#define BX_UNUSED_7(_a1, _a2, _a3, _a4, _a5, _a6, _a7) BX_UNUSED_6(_a1, _a2, _a3, _a4, _a5, _a6); BX_UNUSED_1(_a7) +#define BX_UNUSED_8(_a1, _a2, _a3, _a4, _a5, _a6, _a7, _a8) BX_UNUSED_7(_a1, _a2, _a3, _a4, _a5, _a6, _a7); BX_UNUSED_1(_a8) +#define BX_UNUSED_9(_a1, _a2, _a3, _a4, _a5, _a6, _a7, _a8, _a9) BX_UNUSED_8(_a1, _a2, _a3, _a4, _a5, _a6, _a7, _a8); BX_UNUSED_1(_a9) +#define BX_UNUSED_10(_a1, _a2, _a3, _a4, _a5, _a6, _a7, _a8, _a9, _a10) BX_UNUSED_9(_a1, _a2, _a3, _a4, _a5, _a6, _a7, _a8, _a9); BX_UNUSED_1(_a10) +#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 +// Workaround MSVS bug... +# define BX_UNUSED(...) BX_MACRO_DISPATCHER(BX_UNUSED_, __VA_ARGS__) BX_VA_ARGS_PASS(__VA_ARGS__) +#else +# define BX_UNUSED(...) BX_MACRO_DISPATCHER(BX_UNUSED_, __VA_ARGS__)(__VA_ARGS__) +#endif // BX_COMPILER_MSVC + +/// +#if BX_COMPILER_CLANG +# define BX_PRAGMA_DIAGNOSTIC_PUSH_CLANG() _Pragma("clang diagnostic push") +# define BX_PRAGMA_DIAGNOSTIC_POP_CLANG() _Pragma("clang diagnostic pop") +# define BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG(_x) _Pragma(BX_STRINGIZE(clang diagnostic ignored _x) ) +#else +# define BX_PRAGMA_DIAGNOSTIC_PUSH_CLANG() +# define BX_PRAGMA_DIAGNOSTIC_POP_CLANG() +# define BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG(_x) +#endif // BX_COMPILER_CLANG + +#if BX_COMPILER_GCC && BX_COMPILER_GCC >= 40600 +# define BX_PRAGMA_DIAGNOSTIC_PUSH_GCC() _Pragma("GCC diagnostic push") +# define BX_PRAGMA_DIAGNOSTIC_POP_GCC() _Pragma("GCC diagnostic pop") +# define BX_PRAGMA_DIAGNOSTIC_IGNORED_GCC(_x) _Pragma(BX_STRINGIZE(GCC diagnostic ignored _x) ) +#else +# define BX_PRAGMA_DIAGNOSTIC_PUSH_GCC() +# define BX_PRAGMA_DIAGNOSTIC_POP_GCC() +# define BX_PRAGMA_DIAGNOSTIC_IGNORED_GCC(_x) +#endif // BX_COMPILER_GCC + +#if BX_COMPILER_MSVC +# define BX_PRAGMA_DIAGNOSTIC_PUSH_MSVC() __pragma(warning(push) ) +# define BX_PRAGMA_DIAGNOSTIC_POP_MSVC() __pragma(warning(pop) ) +# define BX_PRAGMA_DIAGNOSTIC_IGNORED_MSVC(_x) __pragma(warning(disable:_x) ) +#else +# define BX_PRAGMA_DIAGNOSTIC_PUSH_MSVC() +# define BX_PRAGMA_DIAGNOSTIC_POP_MSVC() +# define BX_PRAGMA_DIAGNOSTIC_IGNORED_MSVC(_x) +#endif // BX_COMPILER_CLANG + +#if BX_COMPILER_CLANG +# define BX_PRAGMA_DIAGNOSTIC_PUSH BX_PRAGMA_DIAGNOSTIC_PUSH_CLANG +# define BX_PRAGMA_DIAGNOSTIC_POP BX_PRAGMA_DIAGNOSTIC_POP_CLANG +# define BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG_GCC BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG +#elif BX_COMPILER_GCC +# define BX_PRAGMA_DIAGNOSTIC_PUSH BX_PRAGMA_DIAGNOSTIC_PUSH_GCC +# define BX_PRAGMA_DIAGNOSTIC_POP BX_PRAGMA_DIAGNOSTIC_POP_GCC +# define BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG_GCC BX_PRAGMA_DIAGNOSTIC_IGNORED_GCC +#elif BX_COMPILER_MSVC +# define BX_PRAGMA_DIAGNOSTIC_PUSH BX_PRAGMA_DIAGNOSTIC_PUSH_MSVC +# define BX_PRAGMA_DIAGNOSTIC_POP BX_PRAGMA_DIAGNOSTIC_POP_MSVC +# define BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG_GCC(_x) +#endif // BX_COMPILER_ + +/// +#if BX_COMPILER_GCC && defined(__is_pod) +# define BX_TYPE_IS_POD(t) __is_pod(t) +#elif BX_COMPILER_MSVC +# define BX_TYPE_IS_POD(t) (!__is_class(t) || __is_pod(t)) +#else +# define BX_TYPE_IS_POD(t) false +#endif +/// +#define BX_CLASS_NO_DEFAULT_CTOR(_class) \ + private: _class() + +#define BX_CLASS_NO_COPY(_class) \ + private: _class(const _class& _rhs) + +#define BX_CLASS_NO_ASSIGNMENT(_class) \ + private: _class& operator=(const _class& _rhs) + +#define BX_CLASS_ALLOCATOR(_class) \ + public: void* operator new(size_t _size); \ + public: void operator delete(void* _ptr); \ + public: void* operator new[](size_t _size); \ + public: void operator delete[](void* _ptr) + +#define BX_CLASS_1(_class, _a1) BX_CONCATENATE(BX_CLASS_, _a1)(_class) +#define BX_CLASS_2(_class, _a1, _a2) BX_CLASS_1(_class, _a1); BX_CLASS_1(_class, _a2) +#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 +# 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_TRACE +# define BX_TRACE(...) BX_NOOP() +#endif // BX_TRACE + +#ifndef BX_WARN +# define BX_WARN(_condition, ...) BX_NOOP() +#endif // BX_CHECK + +#endif // BX_MACROS_H_HEADER_GUARD diff --git a/deps/include/bx/maputil.h b/deps/include/bx/maputil.h new file mode 100644 index 0000000..f9655f5 --- /dev/null +++ b/deps/include/bx/maputil.h @@ -0,0 +1,29 @@ +/* + * Copyright 2010-2015 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#ifndef BX_MAPUTIL_H_HEADER_GUARD +#define BX_MAPUTIL_H_HEADER_GUARD + +#include "bx.h" + +namespace bx +{ + template + typename MapType::iterator mapInsertOrUpdate(MapType& _map, const typename MapType::key_type& _key, const typename MapType::mapped_type& _value) + { + typename MapType::iterator it = _map.lower_bound(_key); + if (it != _map.end() + && !_map.key_comp()(_key, it->first) ) + { + it->second = _value; + return it; + } + + typename MapType::value_type pair(_key, _value); + return _map.insert(it, pair); + } +} // namespace bx + +#endif // BX_MAPUTIL_H_HEADER_GUARD diff --git a/deps/include/bx/mpscqueue.h b/deps/include/bx/mpscqueue.h new file mode 100644 index 0000000..f0d91e1 --- /dev/null +++ b/deps/include/bx/mpscqueue.h @@ -0,0 +1,54 @@ +/* + * Copyright 2010-2015 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#ifndef BX_MPSCQUEUE_H_HEADER_GUARD +#define BX_MPSCQUEUE_H_HEADER_GUARD + +#include "spscqueue.h" + +namespace bx +{ + template + class MpScUnboundedQueue + { + BX_CLASS(MpScUnboundedQueue + , NO_COPY + , NO_ASSIGNMENT + ); + + public: + MpScUnboundedQueue() + { + } + + ~MpScUnboundedQueue() + { + } + + void push(Ty* _ptr) // producer only + { + m_write.lock(); + m_queue.push(_ptr); + m_write.unlock(); + } + + Ty* peek() // consumer only + { + return m_queue.peek(); + } + + Ty* pop() // consumer only + { + return m_queue.pop(); + } + + private: + LwMutex m_write; + SpScUnboundedQueue m_queue; + }; + +} // namespace bx + +#endif // BX_MPSCQUEUE_H_HEADER_GUARD diff --git a/deps/include/bx/mutex.h b/deps/include/bx/mutex.h new file mode 100644 index 0000000..c0b0e8c --- /dev/null +++ b/deps/include/bx/mutex.h @@ -0,0 +1,148 @@ +/* + * Copyright 2010-2015 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#ifndef BX_MUTEX_H_HEADER_GUARD +#define BX_MUTEX_H_HEADER_GUARD + +#include "bx.h" +#include "cpu.h" +#include "os.h" +#include "sem.h" + +#if BX_CONFIG_SUPPORTS_THREADING + +#if BX_PLATFORM_NACL || BX_PLATFORM_LINUX || BX_PLATFORM_ANDROID || BX_PLATFORM_OSX +# include +#elif BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 || BX_PLATFORM_WINRT +# include +#endif // BX_PLATFORM_ + +namespace bx +{ +#if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 || BX_PLATFORM_WINRT + typedef CRITICAL_SECTION pthread_mutex_t; + typedef unsigned pthread_mutexattr_t; + + inline int pthread_mutex_lock(pthread_mutex_t* _mutex) + { + EnterCriticalSection(_mutex); + return 0; + } + + inline int pthread_mutex_unlock(pthread_mutex_t* _mutex) + { + LeaveCriticalSection(_mutex); + return 0; + } + + inline int pthread_mutex_trylock(pthread_mutex_t* _mutex) + { + return TryEnterCriticalSection(_mutex) ? 0 : EBUSY; + } + + inline int pthread_mutex_init(pthread_mutex_t* _mutex, pthread_mutexattr_t* /*_attr*/) + { +#if BX_PLATFORM_WINRT + InitializeCriticalSectionEx(_mutex, 4000, 0); // docs recommend 4000 spincount as sane default +#else + InitializeCriticalSection(_mutex); +#endif + return 0; + } + + inline int pthread_mutex_destroy(pthread_mutex_t* _mutex) + { + DeleteCriticalSection(_mutex); + return 0; + } +#endif // BX_PLATFORM_ + + class Mutex + { + BX_CLASS(Mutex + , NO_COPY + , NO_ASSIGNMENT + ); + + public: + Mutex() + { + pthread_mutex_init(&m_handle, NULL); + } + + ~Mutex() + { + pthread_mutex_destroy(&m_handle); + } + + void lock() + { + pthread_mutex_lock(&m_handle); + } + + void unlock() + { + pthread_mutex_unlock(&m_handle); + } + + private: + pthread_mutex_t m_handle; + }; + + class MutexScope + { + BX_CLASS(MutexScope + , NO_DEFAULT_CTOR + , NO_COPY + , NO_ASSIGNMENT + ); + + public: + MutexScope(Mutex& _mutex) + : m_mutex(_mutex) + { + m_mutex.lock(); + } + + ~MutexScope() + { + m_mutex.unlock(); + } + + private: + Mutex& m_mutex; + }; + + typedef Mutex LwMutex; + + class LwMutexScope + { + BX_CLASS(LwMutexScope + , NO_DEFAULT_CTOR + , NO_COPY + , NO_ASSIGNMENT + ); + + public: + LwMutexScope(LwMutex& _mutex) + : m_mutex(_mutex) + { + m_mutex.lock(); + } + + ~LwMutexScope() + { + m_mutex.unlock(); + } + + private: + LwMutex& m_mutex; + }; + +} // namespace bx + +#endif // BX_CONFIG_SUPPORTS_THREADING + +#endif // BX_MUTEX_H_HEADER_GUARD diff --git a/deps/include/bx/os.h b/deps/include/bx/os.h new file mode 100644 index 0000000..6fd9fef --- /dev/null +++ b/deps/include/bx/os.h @@ -0,0 +1,209 @@ +/* + * Copyright 2010-2015 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#ifndef BX_OS_H_HEADER_GUARD +#define BX_OS_H_HEADER_GUARD + +#include "bx.h" +#include "debug.h" + +#if BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT +# include +#elif BX_PLATFORM_ANDROID \ + || BX_PLATFORM_EMSCRIPTEN \ + || BX_PLATFORM_FREEBSD \ + || BX_PLATFORM_IOS \ + || BX_PLATFORM_LINUX \ + || BX_PLATFORM_NACL \ + || BX_PLATFORM_OSX \ + || BX_PLATFORM_PS4 \ + || BX_PLATFORM_RPI + +# include // sched_yield +# if BX_PLATFORM_FREEBSD \ + || BX_PLATFORM_IOS \ + || BX_PLATFORM_NACL \ + || BX_PLATFORM_OSX \ + || BX_PLATFORM_PS4 +# include // mach_port_t +# endif // BX_PLATFORM_IOS || BX_PLATFORM_OSX || BX_PLATFORM_NACL + +# if BX_PLATFORM_NACL +# include // nanosleep +# else +# include // nanosleep +# if !BX_PLATFORM_PS4 +# include // dlopen, dlclose, dlsym +# endif // !BX_PLATFORM_PS4 +# endif // BX_PLATFORM_NACL + +# if BX_PLATFORM_LINUX || BX_PLATFORM_RPI +# include // syscall +# include +# endif // BX_PLATFORM_LINUX || BX_PLATFORM_RPI + +# if BX_PLATFORM_ANDROID +# include "debug.h" // getTid is not implemented... +# endif // BX_PLATFORM_ANDROID +#endif // BX_PLATFORM_ + +#if BX_COMPILER_MSVC_COMPATIBLE +# include // _getcwd +#else +# include // getcwd +#endif // BX_COMPILER_MSVC + +#if BX_PLATFORM_OSX +# define BX_DL_EXT "dylib" +#elif BX_PLATFORM_WINDOWS +# define BX_DL_EXT "dll" +#else +# define BX_DL_EXT "so" +#endif // + +namespace bx +{ + inline void sleep(uint32_t _ms) + { +#if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 + ::Sleep(_ms); +#elif BX_PLATFORM_WINRT + BX_UNUSED(_ms); + debugOutput("sleep is not implemented"); debugBreak(); +#else + timespec req = {(time_t)_ms/1000, (long)((_ms%1000)*1000000)}; + timespec rem = {0, 0}; + ::nanosleep(&req, &rem); +#endif // BX_PLATFORM_ + } + + inline void yield() + { +#if BX_PLATFORM_WINDOWS + ::SwitchToThread(); +#elif BX_PLATFORM_XBOX360 + ::Sleep(0); +#elif BX_PLATFORM_WINRT + debugOutput("yield is not implemented"); debugBreak(); +#else + ::sched_yield(); +#endif // BX_PLATFORM_ + } + + inline uint32_t getTid() + { +#if BX_PLATFORM_WINDOWS + return ::GetCurrentThreadId(); +#elif BX_PLATFORM_LINUX || BX_PLATFORM_RPI + return (pid_t)::syscall(SYS_gettid); +#elif BX_PLATFORM_IOS || BX_PLATFORM_OSX + return (mach_port_t)::pthread_mach_thread_np(pthread_self() ); +#elif BX_PLATFORM_FREEBSD || BX_PLATFORM_NACL + // Casting __nc_basic_thread_data*... need better way to do this. + return *(uint32_t*)::pthread_self(); +#else +//# pragma message "not implemented." + debugOutput("getTid is not implemented"); debugBreak(); + return 0; +#endif // + } + + inline void* dlopen(const char* _filePath) + { +#if BX_PLATFORM_WINDOWS + return (void*)::LoadLibraryA(_filePath); +#elif BX_PLATFORM_EMSCRIPTEN \ + || BX_PLATFORM_NACL \ + || BX_PLATFORM_PS4 \ + || BX_PLATFORM_WINRT + BX_UNUSED(_filePath); + return NULL; +#else + return ::dlopen(_filePath, RTLD_LOCAL|RTLD_LAZY); +#endif // BX_PLATFORM_ + } + + inline void dlclose(void* _handle) + { +#if BX_PLATFORM_WINDOWS + ::FreeLibrary( (HMODULE)_handle); +#elif BX_PLATFORM_EMSCRIPTEN \ + || BX_PLATFORM_NACL \ + || BX_PLATFORM_PS4 \ + || BX_PLATFORM_WINRT + BX_UNUSED(_handle); +#else + ::dlclose(_handle); +#endif // BX_PLATFORM_ + } + + inline void* dlsym(void* _handle, const char* _symbol) + { +#if BX_PLATFORM_WINDOWS + return (void*)::GetProcAddress( (HMODULE)_handle, _symbol); +#elif BX_PLATFORM_EMSCRIPTEN \ + || BX_PLATFORM_NACL \ + || BX_PLATFORM_PS4 \ + || BX_PLATFORM_WINRT + BX_UNUSED(_handle, _symbol); + return NULL; +#else + return ::dlsym(_handle, _symbol); +#endif // BX_PLATFORM_ + } + + inline void setenv(const char* _name, const char* _value) + { +#if BX_PLATFORM_WINDOWS + ::SetEnvironmentVariableA(_name, _value); +#elif BX_PLATFORM_PS4 \ + || BX_PLATFORM_WINRT + BX_UNUSED(_name, _value); +#else + ::setenv(_name, _value, 1); +#endif // BX_PLATFORM_ + } + + inline void unsetenv(const char* _name) + { +#if BX_PLATFORM_WINDOWS + ::SetEnvironmentVariableA(_name, NULL); +#elif BX_PLATFORM_PS4 \ + || BX_PLATFORM_WINRT + BX_UNUSED(_name); +#else + ::unsetenv(_name); +#endif // BX_PLATFORM_ + } + + inline int chdir(const char* _path) + { +#if BX_PLATFORM_PS4 \ + || BX_PLATFORM_WINRT + BX_UNUSED(_path); + return -1; +#elif BX_COMPILER_MSVC_COMPATIBLE + return ::_chdir(_path); +#else + return ::chdir(_path); +#endif // BX_COMPILER_ + } + + inline char* pwd(char* _buffer, uint32_t _size) + { +#if BX_PLATFORM_PS4 \ + || BX_PLATFORM_WINRT + BX_UNUSED(_buffer, _size); + return NULL; +#elif BX_COMPILER_MSVC_COMPATIBLE + return ::_getcwd(_buffer, (int)_size); +#else + return ::getcwd(_buffer, _size); +#endif // BX_COMPILER_ + } + +} // namespace bx + +#endif // BX_OS_H_HEADER_GUARD diff --git a/deps/include/bx/platform.h b/deps/include/bx/platform.h new file mode 100644 index 0000000..d272a17 --- /dev/null +++ b/deps/include/bx/platform.h @@ -0,0 +1,310 @@ +/* + * Copyright 2010-2015 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#ifndef BX_PLATFORM_H_HEADER_GUARD +#define BX_PLATFORM_H_HEADER_GUARD + +#define BX_COMPILER_CLANG 0 +#define BX_COMPILER_CLANG_ANALYZER 0 +#define BX_COMPILER_GCC 0 +#define BX_COMPILER_MSVC 0 +#define BX_COMPILER_MSVC_COMPATIBLE 0 + +#define BX_PLATFORM_ANDROID 0 +#define BX_PLATFORM_EMSCRIPTEN 0 +#define BX_PLATFORM_FREEBSD 0 +#define BX_PLATFORM_IOS 0 +#define BX_PLATFORM_LINUX 0 +#define BX_PLATFORM_NACL 0 +#define BX_PLATFORM_OSX 0 +#define BX_PLATFORM_PS4 0 +#define BX_PLATFORM_QNX 0 +#define BX_PLATFORM_RPI 0 +#define BX_PLATFORM_WINDOWS 0 +#define BX_PLATFORM_WINRT 0 +#define BX_PLATFORM_XBOX360 0 +#define BX_PLATFORM_XBOXONE 0 + +#define BX_CPU_ARM 0 +#define BX_CPU_JIT 0 +#define BX_CPU_MIPS 0 +#define BX_CPU_PPC 0 +#define BX_CPU_X86 0 + +#define BX_ARCH_32BIT 0 +#define BX_ARCH_64BIT 0 + +#define BX_CPU_ENDIAN_BIG 0 +#define BX_CPU_ENDIAN_LITTLE 0 + +// http://sourceforge.net/apps/mediawiki/predef/index.php?title=Compilers +#if defined(__clang__) +// clang defines __GNUC__ or _MSC_VER +# undef BX_COMPILER_CLANG +# define BX_COMPILER_CLANG (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) +# if defined(__clang_analyzer__) +# undef BX_COMPILER_CLANG_ANALYZER +# define BX_COMPILER_CLANG_ANALYZER 1 +# endif // defined(__clang_analyzer__) +# if defined(_MSC_VER) +# undef BX_COMPILER_MSVC_COMPATIBLE +# define BX_COMPILER_MSVC_COMPATIBLE _MSC_VER +# endif // defined(_MSC_VER) +#elif defined(_MSC_VER) +# undef BX_COMPILER_MSVC +# define BX_COMPILER_MSVC _MSC_VER +# undef BX_COMPILER_MSVC_COMPATIBLE +# define BX_COMPILER_MSVC_COMPATIBLE _MSC_VER +#elif defined(__GNUC__) +# undef BX_COMPILER_GCC +# define BX_COMPILER_GCC (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) +#else +# error "BX_COMPILER_* is not defined!" +#endif // + +// http://sourceforge.net/apps/mediawiki/predef/index.php?title=Architectures +#if defined(__arm__) || \ + defined(__aarch64__) || \ + defined(_M_ARM) +# undef BX_CPU_ARM +# define BX_CPU_ARM 1 +# define BX_CACHE_LINE_SIZE 64 +#elif defined(__MIPSEL__) || \ + defined(__mips_isa_rev) || \ + defined(__mips64) +# undef BX_CPU_MIPS +# define BX_CPU_MIPS 1 +# define BX_CACHE_LINE_SIZE 64 +#elif defined(_M_PPC) || \ + defined(__powerpc__) || \ + defined(__powerpc64__) +# undef BX_CPU_PPC +# define BX_CPU_PPC 1 +# define BX_CACHE_LINE_SIZE 128 +#elif defined(_M_IX86) || \ + defined(_M_X64) || \ + defined(__i386__) || \ + defined(__x86_64__) +# undef BX_CPU_X86 +# define BX_CPU_X86 1 +# define BX_CACHE_LINE_SIZE 64 +#else // PNaCl doesn't have CPU defined. +# undef BX_CPU_JIT +# define BX_CPU_JIT 1 +# define BX_CACHE_LINE_SIZE 64 +#endif // + +#if defined(__x86_64__) || \ + defined(_M_X64) || \ + defined(__aarch64__) || \ + defined(__64BIT__) || \ + defined(__mips64) || \ + defined(__powerpc64__) || \ + defined(__ppc64__) +# undef BX_ARCH_64BIT +# define BX_ARCH_64BIT 64 +#else +# undef BX_ARCH_32BIT +# define BX_ARCH_32BIT 32 +#endif // + +#if BX_CPU_PPC +# undef BX_CPU_ENDIAN_BIG +# define BX_CPU_ENDIAN_BIG 1 +#else +# undef BX_CPU_ENDIAN_LITTLE +# define BX_CPU_ENDIAN_LITTLE 1 +#endif // BX_PLATFORM_ + +// http://sourceforge.net/apps/mediawiki/predef/index.php?title=Operating_Systems +#if defined(_XBOX_VER) +# undef BX_PLATFORM_XBOX360 +# define BX_PLATFORM_XBOX360 1 +#elif defined (_DURANGO) +# undef BX_PLATFORM_XBOXONE +# define BX_PLATFORM_XBOXONE 1 +#elif defined(_WIN32) || defined(_WIN64) +// http://msdn.microsoft.com/en-us/library/6sehtctf.aspx +# ifndef NOMINMAX +# define NOMINMAX +# endif // NOMINMAX +// If _USING_V110_SDK71_ is defined it means we are using the v110_xp or v120_xp toolset. +# if defined(_MSC_VER) && (_MSC_VER >= 1700) && (!_USING_V110_SDK71_) +# include +# endif // defined(_MSC_VER) && (_MSC_VER >= 1700) && (!_USING_V110_SDK71_) +# if !defined(WINAPI_FAMILY) || (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP) +# undef BX_PLATFORM_WINDOWS +# if !defined(WINVER) && !defined(_WIN32_WINNT) +# if BX_ARCH_64BIT +// When building 64-bit target Win7 and above. +# define WINVER 0x0601 +# define _WIN32_WINNT 0x0601 +# else +// Windows Server 2003 with SP1, Windows XP with SP2 and above +# define WINVER 0x0502 +# define _WIN32_WINNT 0x0502 +# endif // BX_ARCH_64BIT +# endif // !defined(WINVER) && !defined(_WIN32_WINNT) +# define BX_PLATFORM_WINDOWS _WIN32_WINNT +# else +# undef BX_PLATFORM_WINRT +# define BX_PLATFORM_WINRT 1 +# endif +#elif defined(__VCCOREVER__) +// RaspberryPi compiler defines __linux__ +# undef BX_PLATFORM_RPI +# define BX_PLATFORM_RPI 1 +#elif defined(__native_client__) +// NaCl compiler defines __linux__ +# include +# undef BX_PLATFORM_NACL +# define BX_PLATFORM_NACL PPAPI_RELEASE +#elif defined(__ANDROID__) +// Android compiler defines __linux__ +# include +# undef BX_PLATFORM_ANDROID +# define BX_PLATFORM_ANDROID __ANDROID_API__ +#elif defined(__linux__) +# undef BX_PLATFORM_LINUX +# define BX_PLATFORM_LINUX 1 +#elif defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) +# undef BX_PLATFORM_IOS +# define BX_PLATFORM_IOS 1 +#elif defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) +# undef BX_PLATFORM_OSX +# define BX_PLATFORM_OSX 1 +#elif defined(__EMSCRIPTEN__) +# undef BX_PLATFORM_EMSCRIPTEN +# define BX_PLATFORM_EMSCRIPTEN 1 +#elif defined(__ORBIS__) +# undef BX_PLATFORM_PS4 +# define BX_PLATFORM_PS4 1 +#elif defined(__QNX__) +# undef BX_PLATFORM_QNX +# define BX_PLATFORM_QNX 1 +#elif defined(__FreeBSD__) +# undef BX_PLATFORM_FREEBSD +# define BX_PLATFORM_FREEBSD 1 +#else +# error "BX_PLATFORM_* is not defined!" +#endif // + +#define BX_PLATFORM_POSIX (0 \ + || BX_PLATFORM_ANDROID \ + || BX_PLATFORM_EMSCRIPTEN \ + || BX_PLATFORM_FREEBSD \ + || BX_PLATFORM_IOS \ + || BX_PLATFORM_LINUX \ + || BX_PLATFORM_NACL \ + || BX_PLATFORM_OSX \ + || BX_PLATFORM_QNX \ + || BX_PLATFORM_PS4 \ + || BX_PLATFORM_RPI \ + ) + +#ifndef BX_CONFIG_ENABLE_MSVC_LEVEL4_WARNINGS +# define BX_CONFIG_ENABLE_MSVC_LEVEL4_WARNINGS 0 +#endif // BX_CONFIG_ENABLE_MSVC_LEVEL4_WARNINGS + +#if BX_COMPILER_GCC +# define BX_COMPILER_NAME "GCC " \ + BX_STRINGIZE(__GNUC__) "." \ + BX_STRINGIZE(__GNUC_MINOR__) "." \ + BX_STRINGIZE(__GNUC_PATCHLEVEL__) +#elif BX_COMPILER_CLANG +# define BX_COMPILER_NAME "Clang " \ + BX_STRINGIZE(__clang_major__) "." \ + BX_STRINGIZE(__clang_minor__) "." \ + BX_STRINGIZE(__clang_patchlevel__) +#elif BX_COMPILER_MSVC +# if BX_COMPILER_MSVC >= 1900 +# define BX_COMPILER_NAME "MSVC 14.0" +# elif BX_COMPILER_MSVC >= 1800 +# define BX_COMPILER_NAME "MSVC 12.0" +# elif BX_COMPILER_MSVC >= 1700 +# define BX_COMPILER_NAME "MSVC 11.0" +# elif BX_COMPILER_MSVC >= 1600 +# define BX_COMPILER_NAME "MSVC 10.0" +# elif BX_COMPILER_MSVC >= 1500 +# define BX_COMPILER_NAME "MSVC 9.0" +# else +# define BX_COMPILER_NAME "MSVC" +# endif // +#endif // BX_COMPILER_ + +#if BX_PLATFORM_ANDROID +# define BX_PLATFORM_NAME "Android " \ + BX_STRINGIZE(BX_PLATFORM_ANDROID) +#elif BX_PLATFORM_EMSCRIPTEN +# define BX_PLATFORM_NAME "asm.js " \ + BX_STRINGIZE(__EMSCRIPTEN_major__) "." \ + BX_STRINGIZE(__EMSCRIPTEN_minor__) "." \ + BX_STRINGIZE(__EMSCRIPTEN_tiny__) +#elif BX_PLATFORM_FREEBSD +# define BX_PLATFORM_NAME "FreeBSD" +#elif BX_PLATFORM_IOS +# define BX_PLATFORM_NAME "iOS" +#elif BX_PLATFORM_LINUX +# define BX_PLATFORM_NAME "Linux" +#elif BX_PLATFORM_NACL +# define BX_PLATFORM_NAME "NaCl " \ + BX_STRINGIZE(BX_PLATFORM_NACL) +#elif BX_PLATFORM_OSX +# define BX_PLATFORM_NAME "OSX" +#elif BX_PLATFORM_PS4 +# define BX_PLATFORM_NAME "PlayStation 4" +#elif BX_PLATFORM_QNX +# define BX_PLATFORM_NAME "QNX" +#elif BX_PLATFORM_RPI +# define BX_PLATFORM_NAME "RaspberryPi" +#elif BX_PLATFORM_WINDOWS +# define BX_PLATFORM_NAME "Windows" +#elif BX_PLATFORM_WINRT +# define BX_PLATFORM_NAME "WinRT" +#elif BX_PLATFORM_XBOX360 +# define BX_PLATFORM_NAME "Xbox 360" +#elif BX_PLATFORM_XBOXONE +# define BX_PLATFORM_NAME "Xbox One" +#endif // BX_PLATFORM_ + +#if BX_CPU_ARM +# define BX_CPU_NAME "ARM" +#elif BX_CPU_MIPS +# define BX_CPU_NAME "MIPS" +#elif BX_CPU_PPC +# define BX_CPU_NAME "PowerPC" +#elif BX_CPU_JIT +# define BX_CPU_NAME "JIT-VM" +#elif BX_CPU_X86 +# define BX_CPU_NAME "x86" +#endif // BX_CPU_ + +#if BX_ARCH_32BIT +# define BX_ARCH_NAME "32-bit" +#elif BX_ARCH_64BIT +# define BX_ARCH_NAME "64-bit" +#endif // BX_ARCH_ + +#if BX_CONFIG_ENABLE_MSVC_LEVEL4_WARNINGS && BX_COMPILER_MSVC +# pragma warning(error:4062) // ENABLE warning C4062: enumerator'...' in switch of enum '...' is not handled +# pragma warning(error:4121) // ENABLE warning C4121: 'symbol' : alignment of a member was sensitive to packing +//# pragma warning(error:4127) // ENABLE warning C4127: conditional expression is constant +# pragma warning(error:4130) // ENABLE warning C4130: 'operator' : logical operation on address of string constant +# pragma warning(error:4239) // ENABLE warning C4239: nonstandard extension used : 'argument' : conversion from '*' to '* &' A non-const reference may only be bound to an lvalue +//# pragma warning(error:4244) // ENABLE warning C4244: 'argument' : conversion from 'type1' to 'type2', possible loss of data +# pragma warning(error:4245) // ENABLE warning C4245: 'conversion' : conversion from 'type1' to 'type2', signed/unsigned mismatch +# pragma warning(error:4263) // ENABLE warning C4263: 'function' : member function does not override any base class virtual member function +# pragma warning(error:4265) // ENABLE warning C4265: class has virtual functions, but destructor is not virtual +# pragma warning(error:4431) // ENABLE warning C4431: missing type specifier - int assumed. Note: C no longer supports default-int +# pragma warning(error:4545) // ENABLE warning C4545: expression before comma evaluates to a function which is missing an argument list +# pragma warning(error:4549) // ENABLE warning C4549: 'operator' : operator before comma has no effect; did you intend 'operator'? +# pragma warning(error:4701) // ENABLE warning C4701: potentially uninitialized local variable 'name' used +# pragma warning(error:4706) // ENABLE warning C4706: assignment within conditional expression +# pragma warning(error:4100) // ENABLE warning C4100: '' : unreferenced formal parameter +# pragma warning(error:4189) // ENABLE warning C4189: '' : local variable is initialized but not referenced +# pragma warning(error:4505) // ENABLE warning C4505: '' : unreferenced local function has been removed +#endif // BX_CONFIG_ENABLE_MSVC_LEVEL4_WARNINGS && BX_COMPILER_MSVC + +#endif // BX_PLATFORM_H_HEADER_GUARD diff --git a/deps/include/bx/process.h b/deps/include/bx/process.h new file mode 100644 index 0000000..60fc24c --- /dev/null +++ b/deps/include/bx/process.h @@ -0,0 +1,80 @@ +/* + * Copyright 2010-2015 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#ifndef BX_PROCESS_H_HEADER_GUARD +#define BX_PROCESS_H_HEADER_GUARD + +#include "string.h" +#include "uint32_t.h" + +#if BX_PLATFORM_LINUX +# include +#endif // BX_PLATFORM_LINUX + +namespace bx +{ + /// + inline void* exec(const char* const* _argv) + { +#if BX_PLATFORM_LINUX + pid_t pid = fork(); + + if (0 == pid) + { + int result = execvp(_argv[0], const_cast(&_argv[1]) ); + BX_UNUSED(result); + return NULL; + } + + return (void*)uintptr_t(pid); +#elif BX_PLATFORM_WINDOWS + STARTUPINFO si; + memset(&si, 0, sizeof(STARTUPINFO) ); + si.cb = sizeof(STARTUPINFO); + + PROCESS_INFORMATION pi; + memset(&pi, 0, sizeof(PROCESS_INFORMATION) ); + + int32_t total = 0; + for (uint32_t ii = 0; NULL != _argv[ii]; ++ii) + { + total += (int32_t)strlen(_argv[ii]) + 1; + } + + char* temp = (char*)alloca(total); + int32_t len = 0; + for(uint32_t ii = 0; NULL != _argv[ii]; ++ii) + { + len += snprintf(&temp[len], bx::uint32_imax(0, total-len) + , "%s " + , _argv[ii] + ); + } + + bool ok = CreateProcessA(_argv[0] + , temp + , NULL + , NULL + , false + , 0 + , NULL + , NULL + , &si + , &pi + ); + if (ok) + { + return pi.hProcess; + } + + return NULL; +#else + return NULL; +#endif // BX_PLATFORM_LINUX + } + +} // namespace bx + +#endif // BX_PROCESS_H_HEADER_GUARD diff --git a/deps/include/bx/radixsort.h b/deps/include/bx/radixsort.h new file mode 100644 index 0000000..9ed4011 --- /dev/null +++ b/deps/include/bx/radixsort.h @@ -0,0 +1,169 @@ +/* + * Copyright 2010-2015 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#ifndef BX_RADIXSORT_H_HEADER_GUARD +#define BX_RADIXSORT_H_HEADER_GUARD + +#include "bx.h" + +namespace bx +{ +#define BX_RADIXSORT_BITS 11 +#define BX_RADIXSORT_HISTOGRAM_SIZE (1< + void radixSort32(uint32_t* __restrict _keys, uint32_t* __restrict _tempKeys, Ty* __restrict _values, Ty* __restrict _tempValues, uint32_t _size) + { + uint32_t* __restrict keys = _keys; + uint32_t* __restrict tempKeys = _tempKeys; + Ty* __restrict values = _values; + Ty* __restrict tempValues = _tempValues; + + uint32_t histogram[BX_RADIXSORT_HISTOGRAM_SIZE]; + uint16_t shift = 0; + uint32_t pass = 0; + for (; pass < 3; ++pass) + { + memset(histogram, 0, sizeof(uint32_t)*BX_RADIXSORT_HISTOGRAM_SIZE); + + bool sorted = true; + { + uint32_t key = keys[0]; + uint32_t prevKey = key; + for (uint32_t ii = 0; ii < _size; ++ii, prevKey = key) + { + key = keys[ii]; + uint16_t index = (key>>shift)&BX_RADIXSORT_BIT_MASK; + ++histogram[index]; + sorted &= prevKey <= key; + } + } + + if (sorted) + { + goto done; + } + + uint32_t offset = 0; + for (uint32_t ii = 0; ii < BX_RADIXSORT_HISTOGRAM_SIZE; ++ii) + { + uint32_t count = histogram[ii]; + histogram[ii] = offset; + offset += count; + } + + for (uint32_t ii = 0; ii < _size; ++ii) + { + uint32_t key = keys[ii]; + uint16_t index = (key>>shift)&BX_RADIXSORT_BIT_MASK; + uint32_t dest = histogram[index]++; + tempKeys[dest] = key; + tempValues[dest] = values[ii]; + } + + uint32_t* swapKeys = tempKeys; + tempKeys = keys; + keys = swapKeys; + + Ty* swapValues = tempValues; + tempValues = values; + values = swapValues; + + shift += BX_RADIXSORT_BITS; + } + +done: + if (0 != (pass&1) ) + { + // Odd number of passes needs to do copy to the destination. + memcpy(_keys, _tempKeys, _size*sizeof(uint32_t) ); + for (uint32_t ii = 0; ii < _size; ++ii) + { + _values[ii] = _tempValues[ii]; + } + } + } + + template + void radixSort64(uint64_t* __restrict _keys, uint64_t* __restrict _tempKeys, Ty* __restrict _values, Ty* __restrict _tempValues, uint32_t _size) + { + uint64_t* __restrict keys = _keys; + uint64_t* __restrict tempKeys = _tempKeys; + Ty* __restrict values = _values; + Ty* __restrict tempValues = _tempValues; + + uint32_t histogram[BX_RADIXSORT_HISTOGRAM_SIZE]; + uint16_t shift = 0; + uint32_t pass = 0; + for (; pass < 6; ++pass) + { + memset(histogram, 0, sizeof(uint32_t)*BX_RADIXSORT_HISTOGRAM_SIZE); + + bool sorted = true; + { + uint64_t key = keys[0]; + uint64_t prevKey = key; + for (uint32_t ii = 0; ii < _size; ++ii, prevKey = key) + { + key = keys[ii]; + uint16_t index = (key>>shift)&BX_RADIXSORT_BIT_MASK; + ++histogram[index]; + sorted &= prevKey <= key; + } + } + + if (sorted) + { + goto done; + } + + uint32_t offset = 0; + for (uint32_t ii = 0; ii < BX_RADIXSORT_HISTOGRAM_SIZE; ++ii) + { + uint32_t count = histogram[ii]; + histogram[ii] = offset; + offset += count; + } + + for (uint32_t ii = 0; ii < _size; ++ii) + { + uint64_t key = keys[ii]; + uint16_t index = (key>>shift)&BX_RADIXSORT_BIT_MASK; + uint32_t dest = histogram[index]++; + tempKeys[dest] = key; + tempValues[dest] = values[ii]; + } + + uint64_t* swapKeys = tempKeys; + tempKeys = keys; + keys = swapKeys; + + Ty* swapValues = tempValues; + tempValues = values; + values = swapValues; + + shift += BX_RADIXSORT_BITS; + } + +done: + if (0 != (pass&1) ) + { + // Odd number of passes needs to do copy to the destination. + memcpy(_keys, _tempKeys, _size*sizeof(uint64_t) ); + for (uint32_t ii = 0; ii < _size; ++ii) + { + _values[ii] = _tempValues[ii]; + } + } + } + +#undef BX_RADIXSORT_BITS +#undef BX_RADIXSORT_HISTOGRAM_SIZE +#undef BX_RADIXSORT_BIT_MASK + +} // namespace bx + +#endif // BX_RADIXSORT_H_HEADER_GUARD diff --git a/deps/include/bx/readerwriter.h b/deps/include/bx/readerwriter.h new file mode 100644 index 0000000..3d681b8 --- /dev/null +++ b/deps/include/bx/readerwriter.h @@ -0,0 +1,589 @@ +/* + * Copyright 2010-2015 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#ifndef BX_READERWRITER_H_HEADER_GUARD +#define BX_READERWRITER_H_HEADER_GUARD + +#include // va_list +#include +#include + +#include "bx.h" +#include "allocator.h" +#include "uint32_t.h" + +#if BX_COMPILER_MSVC_COMPATIBLE +# define fseeko64 _fseeki64 +# define ftello64 _ftelli64 +#elif BX_PLATFORM_ANDROID || BX_PLATFORM_FREEBSD || BX_PLATFORM_IOS || BX_PLATFORM_OSX || BX_PLATFORM_QNX +# define fseeko64 fseeko +# define ftello64 ftello +#endif // BX_ + +namespace bx +{ + struct Whence + { + enum Enum + { + Begin, + Current, + End, + }; + }; + + struct BX_NO_VTABLE ReaderI + { + virtual ~ReaderI() = 0; + virtual int32_t read(void* _data, int32_t _size) = 0; + }; + + inline ReaderI::~ReaderI() + { + } + + struct BX_NO_VTABLE WriterI + { + virtual ~WriterI() = 0; + virtual int32_t write(const void* _data, int32_t _size) = 0; + }; + + inline WriterI::~WriterI() + { + } + + struct BX_NO_VTABLE SeekerI + { + virtual ~SeekerI() = 0; + virtual int64_t seek(int64_t _offset = 0, Whence::Enum _whence = Whence::Current) = 0; + }; + + inline SeekerI::~SeekerI() + { + } + + /// Read data. + inline int32_t read(ReaderI* _reader, void* _data, int32_t _size) + { + return _reader->read(_data, _size); + } + + /// Write value. + template + inline int32_t read(ReaderI* _reader, Ty& _value) + { + BX_STATIC_ASSERT(BX_TYPE_IS_POD(Ty) ); + return _reader->read(&_value, sizeof(Ty) ); + } + + /// Read value and converts it to host endianess. _fromLittleEndian specifies + /// underlying stream endianess. + template + inline int32_t readHE(ReaderI* _reader, Ty& _value, bool _fromLittleEndian) + { + BX_STATIC_ASSERT(BX_TYPE_IS_POD(Ty) ); + Ty value; + int32_t result = _reader->read(&value, sizeof(Ty) ); + _value = toHostEndian(value, _fromLittleEndian); + return result; + } + + /// Write data. + inline int32_t write(WriterI* _writer, const void* _data, int32_t _size) + { + return _writer->write(_data, _size); + } + + /// Write repeat the same value. + inline int32_t writeRep(WriterI* _writer, uint8_t _byte, int32_t _size) + { + const uint32_t tmp0 = uint32_sels(64 - _size, 64, _size); + const uint32_t tmp1 = uint32_sels(256 - _size, 256, tmp0); + const uint32_t blockSize = uint32_sels(1024 - _size, 1024, tmp1); + uint8_t* temp = (uint8_t*)alloca(blockSize); + memset(temp, _byte, blockSize); + + int32_t size = 0; + while (0 < _size) + { + int32_t bytes = write(_writer, temp, uint32_min(blockSize, _size) ); + size += bytes; + _size -= bytes; + } + + return size; + } + + /// Write value. + template + inline int32_t write(WriterI* _writer, const Ty& _value) + { + BX_STATIC_ASSERT(BX_TYPE_IS_POD(Ty) ); + return _writer->write(&_value, sizeof(Ty) ); + } + + /// Write value as little endian. + template + inline int32_t writeLE(WriterI* _writer, const Ty& _value) + { + BX_STATIC_ASSERT(BX_TYPE_IS_POD(Ty) ); + Ty value = toLittleEndian(_value); + int32_t result = _writer->write(&value, sizeof(Ty) ); + return result; + } + + /// Write value as big endian. + template + inline int32_t writeBE(WriterI* _writer, const Ty& _value) + { + BX_STATIC_ASSERT(BX_TYPE_IS_POD(Ty) ); + Ty value = toBigEndian(_value); + int32_t result = _writer->write(&value, sizeof(Ty) ); + return result; + } + + /// Write formated string. + inline int32_t writePrintf(WriterI* _writer, const char* _format, ...) + { + va_list argList; + va_start(argList, _format); + + char temp[2048]; + char* out = temp; + int32_t max = sizeof(temp); + int32_t len = vsnprintf(out, max, _format, argList); + if (len > max) + { + out = (char*)alloca(len); + len = vsnprintf(out, len, _format, argList); + } + + int32_t size = write(_writer, out, len); + + va_end(argList); + + return size; + } + + /// Skip _offset bytes forward. + inline int64_t skip(SeekerI* _seeker, int64_t _offset) + { + return _seeker->seek(_offset, Whence::Current); + } + + /// Seek to any position in file. + inline int64_t seek(SeekerI* _seeker, int64_t _offset = 0, Whence::Enum _whence = Whence::Current) + { + return _seeker->seek(_offset, _whence); + } + + /// Returns size of file. + inline int64_t getSize(SeekerI* _seeker) + { + int64_t offset = _seeker->seek(); + int64_t size = _seeker->seek(0, Whence::End); + _seeker->seek(offset, Whence::Begin); + return size; + } + + struct BX_NO_VTABLE ReaderSeekerI : public ReaderI, public SeekerI + { + }; + + struct BX_NO_VTABLE WriterSeekerI : public WriterI, public SeekerI + { + }; + + struct BX_NO_VTABLE FileReaderI : public ReaderSeekerI + { + virtual int32_t open(const char* _filePath) = 0; + virtual int32_t close() = 0; + }; + + struct BX_NO_VTABLE FileWriterI : public WriterSeekerI + { + virtual int32_t open(const char* _filePath, bool _append = false) = 0; + virtual int32_t close() = 0; + }; + + inline int32_t open(FileReaderI* _reader, const char* _filePath) + { + return _reader->open(_filePath); + } + + inline int32_t close(FileReaderI* _reader) + { + return _reader->close(); + } + + inline int32_t open(FileWriterI* _writer, const char* _filePath, bool _append = false) + { + return _writer->open(_filePath, _append); + } + + inline int32_t close(FileWriterI* _writer) + { + return _writer->close(); + } + + struct BX_NO_VTABLE MemoryBlockI + { + virtual void* more(uint32_t _size = 0) = 0; + virtual uint32_t getSize() = 0; + }; + + class StaticMemoryBlock : public MemoryBlockI + { + public: + StaticMemoryBlock(void* _data, uint32_t _size) + : m_data(_data) + , m_size(_size) + { + } + + virtual ~StaticMemoryBlock() + { + } + + virtual void* more(uint32_t /*_size*/ = 0) BX_OVERRIDE + { + return m_data; + } + + virtual uint32_t getSize() BX_OVERRIDE + { + return m_size; + } + + private: + void* m_data; + uint32_t m_size; + }; + + class MemoryBlock : public MemoryBlockI + { + public: + MemoryBlock(ReallocatorI* _allocator) + : m_allocator(_allocator) + , m_data(NULL) + , m_size(0) + { + } + + virtual ~MemoryBlock() + { + BX_FREE(m_allocator, m_data); + } + + virtual void* more(uint32_t _size = 0) BX_OVERRIDE + { + if (0 < _size) + { + m_size += _size; + m_data = BX_REALLOC(m_allocator, m_data, m_size); + } + + return m_data; + } + + virtual uint32_t getSize() BX_OVERRIDE + { + return m_size; + } + + private: + ReallocatorI* m_allocator; + void* m_data; + uint32_t m_size; + }; + + class SizerWriter : public WriterSeekerI + { + public: + SizerWriter() + : m_pos(0) + , m_top(0) + { + } + + virtual ~SizerWriter() + { + } + + virtual int64_t seek(int64_t _offset = 0, Whence::Enum _whence = Whence::Current) BX_OVERRIDE + { + switch (_whence) + { + case Whence::Begin: + m_pos = _offset; + break; + + case Whence::Current: + m_pos = int64_clamp(m_pos + _offset, 0, m_top); + break; + + case Whence::End: + m_pos = int64_clamp(m_top - _offset, 0, m_top); + break; + } + + return m_pos; + } + + virtual int32_t write(const void* /*_data*/, int32_t _size) BX_OVERRIDE + { + int32_t morecore = int32_t(m_pos - m_top) + _size; + + if (0 < morecore) + { + m_top += morecore; + } + + int64_t reminder = m_top-m_pos; + int32_t size = uint32_min(_size, int32_t(reminder > INT32_MAX ? INT32_MAX : reminder) ); + m_pos += size; + return size; + } + + private: + int64_t m_pos; + int64_t m_top; + }; + + class MemoryReader : public ReaderSeekerI + { + public: + MemoryReader(const void* _data, uint32_t _size) + : m_data( (const uint8_t*)_data) + , m_pos(0) + , m_top(_size) + { + } + + virtual ~MemoryReader() + { + } + + virtual int64_t seek(int64_t _offset, Whence::Enum _whence) BX_OVERRIDE + { + switch (_whence) + { + case Whence::Begin: + m_pos = _offset; + break; + + case Whence::Current: + m_pos = int64_clamp(m_pos + _offset, 0, m_top); + break; + + case Whence::End: + m_pos = int64_clamp(m_top - _offset, 0, m_top); + break; + } + + return m_pos; + } + + virtual int32_t read(void* _data, int32_t _size) BX_OVERRIDE + { + int64_t reminder = m_top-m_pos; + int32_t size = uint32_min(_size, int32_t(reminder > INT32_MAX ? INT32_MAX : reminder) ); + memcpy(_data, &m_data[m_pos], size); + m_pos += size; + return size; + } + + const uint8_t* getDataPtr() const + { + return &m_data[m_pos]; + } + + int64_t getPos() const + { + return m_pos; + } + + int64_t remaining() const + { + return m_top-m_pos; + } + + private: + const uint8_t* m_data; + int64_t m_pos; + int64_t m_top; + }; + + class MemoryWriter : public WriterSeekerI + { + public: + MemoryWriter(MemoryBlockI* _memBlock) + : m_memBlock(_memBlock) + , m_data(NULL) + , m_pos(0) + , m_top(0) + , m_size(0) + { + } + + virtual ~MemoryWriter() + { + } + + virtual int64_t seek(int64_t _offset = 0, Whence::Enum _whence = Whence::Current) BX_OVERRIDE + { + switch (_whence) + { + case Whence::Begin: + m_pos = _offset; + break; + + case Whence::Current: + m_pos = int64_clamp(m_pos + _offset, 0, m_top); + break; + + case Whence::End: + m_pos = int64_clamp(m_top - _offset, 0, m_top); + break; + } + + return m_pos; + } + + virtual int32_t write(const void* _data, int32_t _size) BX_OVERRIDE + { + int32_t morecore = int32_t(m_pos - m_size) + _size; + + if (0 < morecore) + { + morecore = BX_ALIGN_MASK(morecore, 0xfff); + m_data = (uint8_t*)m_memBlock->more(morecore); + m_size = m_memBlock->getSize(); + } + + int64_t reminder = m_size-m_pos; + int32_t size = uint32_min(_size, int32_t(reminder > INT32_MAX ? INT32_MAX : reminder) ); + memcpy(&m_data[m_pos], _data, size); + m_pos += size; + m_top = int64_max(m_top, m_pos); + return size; + } + + private: + MemoryBlockI* m_memBlock; + uint8_t* m_data; + int64_t m_pos; + int64_t m_top; + int64_t m_size; + }; + + class StaticMemoryBlockWriter : public MemoryWriter + { + public: + StaticMemoryBlockWriter(void* _data, uint32_t _size) + : MemoryWriter(&m_smb) + , m_smb(_data, _size) + { + } + + ~StaticMemoryBlockWriter() + { + } + + private: + StaticMemoryBlock m_smb; + }; + +#if BX_CONFIG_CRT_FILE_READER_WRITER + class CrtFileReader : public FileReaderI + { + public: + CrtFileReader() + : m_file(NULL) + { + } + + virtual ~CrtFileReader() + { + } + + virtual int32_t open(const char* _filePath) BX_OVERRIDE + { + m_file = fopen(_filePath, "rb"); + return NULL == m_file; + } + + virtual int32_t close() BX_OVERRIDE + { + fclose(m_file); + return 0; + } + + virtual int64_t seek(int64_t _offset = 0, Whence::Enum _whence = Whence::Current) BX_OVERRIDE + { + fseeko64(m_file, _offset, _whence); + return ftello64(m_file); + } + + virtual int32_t read(void* _data, int32_t _size) BX_OVERRIDE + { + return (int32_t)fread(_data, 1, _size, m_file); + } + + private: + FILE* m_file; + }; + + class CrtFileWriter : public FileWriterI + { + public: + CrtFileWriter() + : m_file(NULL) + { + } + + virtual ~CrtFileWriter() + { + } + + virtual int32_t open(const char* _filePath, bool _append = false) BX_OVERRIDE + { + if (_append) + { + m_file = fopen(_filePath, "ab"); + } + else + { + m_file = fopen(_filePath, "wb"); + } + + return NULL == m_file; + } + + virtual int32_t close() BX_OVERRIDE + { + fclose(m_file); + return 0; + } + + virtual int64_t seek(int64_t _offset = 0, Whence::Enum _whence = Whence::Current) BX_OVERRIDE + { + fseeko64(m_file, _offset, _whence); + return ftello64(m_file); + } + + virtual int32_t write(const void* _data, int32_t _size) BX_OVERRIDE + { + return (int32_t)fwrite(_data, 1, _size, m_file); + } + + private: + FILE* m_file; + }; +#endif // BX_CONFIG_CRT_FILE_READER_WRITER + +} // namespace bx + +#endif // BX_READERWRITER_H_HEADER_GUARD diff --git a/deps/include/bx/ringbuffer.h b/deps/include/bx/ringbuffer.h new file mode 100644 index 0000000..8b24e0e --- /dev/null +++ b/deps/include/bx/ringbuffer.h @@ -0,0 +1,342 @@ +/* + * Copyright 2010-2015 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#ifndef BX_RINGBUFFER_H_HEADER_GUARD +#define BX_RINGBUFFER_H_HEADER_GUARD + +#include "bx.h" +#include "cpu.h" +#include "uint32_t.h" + +namespace bx +{ + class RingBufferControl + { + BX_CLASS(RingBufferControl + , NO_COPY + , NO_ASSIGNMENT + ); + + public: + RingBufferControl(uint32_t _size) + : m_size(_size) + , m_current(0) + , m_write(0) + , m_read(0) + { + } + + ~RingBufferControl() + { + } + + uint32_t available() const + { + return distance(m_read, m_current); + } + + uint32_t consume(uint32_t _size) // consumer only + { + const uint32_t maxSize = distance(m_read, m_current); + const uint32_t sizeNoSign = uint32_and(_size, 0x7fffffff); + const uint32_t test = uint32_sub(sizeNoSign, maxSize); + const uint32_t size = uint32_sels(test, _size, maxSize); + const uint32_t advance = uint32_add(m_read, size); + const uint32_t read = uint32_mod(advance, m_size); + m_read = read; + return size; + } + + uint32_t reserve(uint32_t _size) // producer only + { + const uint32_t dist = distance(m_write, m_read)-1; + const uint32_t maxSize = uint32_sels(dist, m_size-1, dist); + const uint32_t sizeNoSign = uint32_and(_size, 0x7fffffff); + const uint32_t test = uint32_sub(sizeNoSign, maxSize); + const uint32_t size = uint32_sels(test, _size, maxSize); + const uint32_t advance = uint32_add(m_write, size); + const uint32_t write = uint32_mod(advance, m_size); + m_write = write; + return size; + } + + uint32_t commit(uint32_t _size) // producer only + { + const uint32_t maxSize = distance(m_current, m_write); + const uint32_t sizeNoSign = uint32_and(_size, 0x7fffffff); + const uint32_t test = uint32_sub(sizeNoSign, maxSize); + const uint32_t size = uint32_sels(test, _size, maxSize); + const uint32_t advance = uint32_add(m_current, size); + const uint32_t current = uint32_mod(advance, m_size); + m_current = current; + return size; + } + + uint32_t distance(uint32_t _from, uint32_t _to) const // both + { + const uint32_t diff = uint32_sub(_to, _from); + const uint32_t le = uint32_add(m_size, diff); + const uint32_t result = uint32_sels(diff, le, diff); + + return result; + } + + void reset() + { + m_current = 0; + m_write = 0; + m_read = 0; + } + + const uint32_t m_size; + uint32_t m_current; + uint32_t m_write; + uint32_t m_read; + }; + + class SpScRingBufferControl + { + BX_CLASS(SpScRingBufferControl + , NO_COPY + , NO_ASSIGNMENT + ); + + public: + SpScRingBufferControl(uint32_t _size) + : m_size(_size) + , m_current(0) + , m_write(0) + , m_read(0) + { + } + + ~SpScRingBufferControl() + { + } + + uint32_t available() const + { + return distance(m_read, m_current); + } + + uint32_t consume(uint32_t _size) // consumer only + { + const uint32_t maxSize = distance(m_read, m_current); + const uint32_t sizeNoSign = uint32_and(_size, 0x7fffffff); + const uint32_t test = uint32_sub(sizeNoSign, maxSize); + const uint32_t size = uint32_sels(test, _size, maxSize); + const uint32_t advance = uint32_add(m_read, size); + const uint32_t read = uint32_mod(advance, m_size); + m_read = read; + return size; + } + + uint32_t reserve(uint32_t _size) // producer only + { + const uint32_t dist = distance(m_write, m_read)-1; + const uint32_t maxSize = uint32_sels(dist, m_size-1, dist); + const uint32_t sizeNoSign = uint32_and(_size, 0x7fffffff); + const uint32_t test = uint32_sub(sizeNoSign, maxSize); + const uint32_t size = uint32_sels(test, _size, maxSize); + const uint32_t advance = uint32_add(m_write, size); + const uint32_t write = uint32_mod(advance, m_size); + m_write = write; + return size; + } + + uint32_t commit(uint32_t _size) // producer only + { + const uint32_t maxSize = distance(m_current, m_write); + const uint32_t sizeNoSign = uint32_and(_size, 0x7fffffff); + const uint32_t test = uint32_sub(sizeNoSign, maxSize); + const uint32_t size = uint32_sels(test, _size, maxSize); + const uint32_t advance = uint32_add(m_current, size); + const uint32_t current = uint32_mod(advance, m_size); + + // must commit all memory writes before moving m_current pointer + // once m_current pointer moves data is used by consumer thread + memoryBarrier(); + m_current = current; + return size; + } + + uint32_t distance(uint32_t _from, uint32_t _to) const // both + { + const uint32_t diff = uint32_sub(_to, _from); + const uint32_t le = uint32_add(m_size, diff); + const uint32_t result = uint32_sels(diff, le, diff); + + return result; + } + + void reset() + { + m_current = 0; + m_write = 0; + m_read = 0; + } + + const uint32_t m_size; + uint32_t m_current; + uint32_t m_write; + uint32_t m_read; + }; + + template + class ReadRingBufferT + { + BX_CLASS(ReadRingBufferT + , NO_DEFAULT_CTOR + , NO_COPY + , NO_ASSIGNMENT + ); + + public: + ReadRingBufferT(Control& _control, const char* _buffer, uint32_t _size) + : m_control(_control) + , m_read(_control.m_read) + , m_end(m_read+_size) + , m_size(_size) + , m_buffer(_buffer) + { + BX_CHECK(_control.available() >= _size, "%d >= %d", _control.available(), _size); + } + + ~ReadRingBufferT() + { + } + + void end() + { + m_control.consume(m_size); + } + + void read(char* _data, uint32_t _len) + { + const uint32_t eof = (m_read + _len) % m_control.m_size; + uint32_t wrap = 0; + const char* from = &m_buffer[m_read]; + + if (eof < m_read) + { + wrap = m_control.m_size - m_read; + memcpy(_data, from, wrap); + _data += wrap; + from = (const char*)&m_buffer[0]; + } + + memcpy(_data, from, _len-wrap); + + m_read = eof; + } + + void skip(uint32_t _len) + { + m_read += _len; + m_read %= m_control.m_size; + } + + private: + template + friend class WriteRingBufferT; + + Control& m_control; + uint32_t m_read; + uint32_t m_end; + const uint32_t m_size; + const char* m_buffer; + }; + + typedef ReadRingBufferT ReadRingBuffer; + typedef ReadRingBufferT SpScReadRingBuffer; + + template + class WriteRingBufferT + { + BX_CLASS(WriteRingBufferT + , NO_DEFAULT_CTOR + , NO_COPY + , NO_ASSIGNMENT + ); + + public: + WriteRingBufferT(Control& _control, char* _buffer, uint32_t _size) + : m_control(_control) + , m_size(_size) + , m_buffer(_buffer) + { + uint32_t size = m_control.reserve(_size); + BX_UNUSED(size); + BX_CHECK(size == _size, "%d == %d", size, _size); + m_write = m_control.m_current; + m_end = m_write+_size; + } + + ~WriteRingBufferT() + { + } + + void end() + { + m_control.commit(m_size); + } + + void write(const char* _data, uint32_t _len) + { + const uint32_t eof = (m_write + _len) % m_control.m_size; + uint32_t wrap = 0; + char* to = &m_buffer[m_write]; + + if (eof < m_write) + { + wrap = m_control.m_size - m_write; + memcpy(to, _data, wrap); + _data += wrap; + to = (char*)&m_buffer[0]; + } + + memcpy(to, _data, _len-wrap); + + m_write = eof; + } + + void write(ReadRingBufferT& _read, uint32_t _len) + { + const uint32_t eof = (_read.m_read + _len) % _read.m_control.m_size; + uint32_t wrap = 0; + const char* from = &_read.m_buffer[_read.m_read]; + + if (eof < _read.m_read) + { + wrap = _read.m_control.m_size - _read.m_read; + write(from, wrap); + from = (const char*)&_read.m_buffer[0]; + } + + write(from, _len-wrap); + + _read.m_read = eof; + } + + void skip(uint32_t _len) + { + m_write += _len; + m_write %= m_control.m_size; + } + + private: + Control& m_control; + uint32_t m_write; + uint32_t m_end; + const uint32_t m_size; + char* m_buffer; + }; + + typedef WriteRingBufferT WriteRingBuffer; + typedef WriteRingBufferT SpScWriteRingBuffer; + +} // namespace bx + +#endif // BX_RINGBUFFER_H_HEADER_GUARD diff --git a/deps/include/bx/rng.h b/deps/include/bx/rng.h new file mode 100644 index 0000000..f52e5eb --- /dev/null +++ b/deps/include/bx/rng.h @@ -0,0 +1,182 @@ +/* + * Copyright 2010-2015 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#ifndef BX_RNG_H_HEADER_GUARD +#define BX_RNG_H_HEADER_GUARD + +#include "bx.h" +#include "fpumath.h" + +namespace bx +{ + // George Marsaglia's MWC + class RngMwc + { + public: + RngMwc(uint32_t _z = 12345, uint32_t _w = 65435) + : m_z(_z) + , m_w(_w) + { + } + + void reset(uint32_t _z = 12345, uint32_t _w = 65435) + { + m_z = _z; + m_w = _w; + } + + uint32_t gen() + { + m_z = 36969*(m_z&65535)+(m_z>>16); + m_w = 18000*(m_w&65535)+(m_w>>16); + return (m_z<<16)+m_w; + } + + private: + uint32_t m_z; + uint32_t m_w; + }; + + // George Marsaglia's FIB + class RngFib + { + public: + RngFib() + : m_a(9983651) + , m_b(95746118) + { + } + + void reset() + { + m_a = 9983651; + m_b = 95746118; + } + + uint32_t gen() + { + m_b = m_a+m_b; + m_a = m_b-m_a; + return m_a; + } + + private: + uint32_t m_a; + uint32_t m_b; + }; + + // George Marsaglia's SHR3 + class RngShr3 + { + public: + RngShr3(uint32_t _jsr = 34221) + : m_jsr(_jsr) + { + } + + void reset(uint32_t _jsr = 34221) + { + m_jsr = _jsr; + } + + uint32_t gen() + { + m_jsr ^= m_jsr<<17; + m_jsr ^= m_jsr>>13; + m_jsr ^= m_jsr<<5; + return m_jsr; + } + + private: + uint32_t m_jsr; + }; + + /// Returns random number between 0.0f and 1.0f. + template + inline float frnd(Ty* _rng) + { + uint32_t rnd = _rng->gen() & UINT16_MAX; + return float(rnd) * 1.0f/float(UINT16_MAX); + } + + /// Returns random number between -1.0f and 1.0f. + template + inline float frndh(Ty* _rng) + { + return 2.0f * bx::frnd(_rng) - 1.0f; + } + + /// Generate random point on unit sphere. + template + static inline void randUnitSphere(float _result[3], Ty* _rng) + { + float rand0 = frnd(_rng) * 2.0f - 1.0f; + float rand1 = frnd(_rng) * pi * 2.0f; + + float sqrtf1 = sqrtf(1.0f - rand0*rand0); + _result[0] = sqrtf1 * cosf(rand1); + _result[1] = sqrtf1 * sinf(rand1); + _result[2] = rand0; + } + + /// Generate random point on unit hemisphere. + template + static inline void randUnitHemisphere(float _result[3], Ty* _rng, const float _normal[3]) + { + float dir[3]; + randUnitSphere(dir, _rng); + + float DdotN = dir[0]*_normal[0] + + dir[1]*_normal[1] + + dir[2]*_normal[2] + ; + + if (0.0f > DdotN) + { + dir[0] = -dir[0]; + dir[1] = -dir[1]; + dir[2] = -dir[2]; + } + + _result[0] = dir[0]; + _result[1] = dir[1]; + _result[2] = dir[2]; + } + + /// Sampling with Hammersley and Halton Points + /// http://www.cse.cuhk.edu.hk/~ttwong/papers/udpoint/udpoints.html + /// + static inline void generateSphereHammersley(void* _data, uint32_t _stride, uint32_t _num, float _scale = 1.0f) + { + uint8_t* data = (uint8_t*)_data; + + for (uint32_t ii = 0; ii < _num; ii++) + { + float tt = 0.0f; + float pp = 0.5; + for (uint32_t jj = ii; jj; jj >>= 1) + { + tt += (jj & 1) ? pp : 0.0f; + pp *= 0.5f; + } + + tt = 2.0f * tt - 1.0f; + + const float phi = (ii + 0.5f) / _num; + const float phirad = phi * 2.0f * pi; + const float st = sqrtf(1.0f-tt*tt) * _scale; + + float* xyz = (float*)data; + data += _stride; + + xyz[0] = st * cosf(phirad); + xyz[1] = st * sinf(phirad); + xyz[2] = tt * _scale; + } + } + +} // namespace bx + +#endif // BX_RNG_H_HEADER_GUARD diff --git a/deps/include/bx/sem.h b/deps/include/bx/sem.h new file mode 100644 index 0000000..785bff3 --- /dev/null +++ b/deps/include/bx/sem.h @@ -0,0 +1,243 @@ +/* + * Copyright 2010-2015 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#ifndef BX_SEM_H_HEADER_GUARD +#define BX_SEM_H_HEADER_GUARD + +#include "bx.h" +#include "mutex.h" + +#if BX_CONFIG_SUPPORTS_THREADING + +#if BX_PLATFORM_POSIX +# include +# include +# include +# include +#elif BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 || BX_PLATFORM_WINRT +# include +# include +#endif // BX_PLATFORM_ + +namespace bx +{ +#if BX_PLATFORM_POSIX + +# if BX_CONFIG_SEMAPHORE_PTHREAD + class Semaphore + { + BX_CLASS(Semaphore + , NO_COPY + , NO_ASSIGNMENT + ); + + public: + Semaphore() + : m_count(0) + { + int result; + result = pthread_mutex_init(&m_mutex, NULL); + BX_CHECK(0 == result, "pthread_mutex_init %d", result); + + result = pthread_cond_init(&m_cond, NULL); + BX_CHECK(0 == result, "pthread_cond_init %d", result); + + BX_UNUSED(result); + } + + ~Semaphore() + { + int result; + result = pthread_cond_destroy(&m_cond); + BX_CHECK(0 == result, "pthread_cond_destroy %d", result); + + result = pthread_mutex_destroy(&m_mutex); + BX_CHECK(0 == result, "pthread_mutex_destroy %d", result); + + BX_UNUSED(result); + } + + void post(uint32_t _count = 1) + { + int result = pthread_mutex_lock(&m_mutex); + BX_CHECK(0 == result, "pthread_mutex_lock %d", result); + + for (uint32_t ii = 0; ii < _count; ++ii) + { + result = pthread_cond_signal(&m_cond); + BX_CHECK(0 == result, "pthread_cond_signal %d", result); + } + + m_count += _count; + + result = pthread_mutex_unlock(&m_mutex); + BX_CHECK(0 == result, "pthread_mutex_unlock %d", result); + + BX_UNUSED(result); + } + + bool wait(int32_t _msecs = -1) + { + int result = pthread_mutex_lock(&m_mutex); + BX_CHECK(0 == result, "pthread_mutex_lock %d", result); + +# if BX_PLATFORM_NACL || BX_PLATFORM_OSX || BX_PLATFORM_IOS + BX_UNUSED(_msecs); + BX_CHECK(-1 == _msecs, "NaCl, iOS and OSX don't support pthread_cond_timedwait at this moment."); + while (0 == result + && 0 >= m_count) + { + result = pthread_cond_wait(&m_cond, &m_mutex); + } +# else + timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + ts.tv_sec += _msecs/1000; + ts.tv_nsec += (_msecs%1000)*1000; + + while (0 == result + && 0 >= m_count) + { + result = pthread_cond_timedwait(&m_cond, &m_mutex, &ts); + } +# endif // BX_PLATFORM_NACL || BX_PLATFORM_OSX + bool ok = 0 == result; + + if (ok) + { + --m_count; + } + + result = pthread_mutex_unlock(&m_mutex); + BX_CHECK(0 == result, "pthread_mutex_unlock %d", result); + + BX_UNUSED(result); + + return ok; + } + + private: + pthread_mutex_t m_mutex; + pthread_cond_t m_cond; + int32_t m_count; + }; + +# else + + class Semaphore + { + BX_CLASS(Semaphore + , NO_COPY + , NO_ASSIGNMENT + ); + + public: + Semaphore() + { + int32_t result = sem_init(&m_handle, 0, 0); + BX_CHECK(0 == result, "sem_init failed. errno %d", errno); + BX_UNUSED(result); + } + + ~Semaphore() + { + int32_t result = sem_destroy(&m_handle); + BX_CHECK(0 == result, "sem_destroy failed. errno %d", errno); + BX_UNUSED(result); + } + + void post(uint32_t _count = 1) + { + int32_t result; + for (uint32_t ii = 0; ii < _count; ++ii) + { + result = sem_post(&m_handle); + BX_CHECK(0 == result, "sem_post failed. errno %d", errno); + } + BX_UNUSED(result); + } + + bool wait(int32_t _msecs = -1) + { +# if BX_PLATFORM_NACL || BX_PLATFORM_OSX + BX_CHECK(-1 == _msecs, "NaCl and OSX don't support sem_timedwait at this moment."); BX_UNUSED(_msecs); + return 0 == sem_wait(&m_handle); +# else + if (0 > _msecs) + { + int32_t result; + do + { + result = sem_wait(&m_handle); + } // keep waiting when interrupted by a signal handler... + while (-1 == result && EINTR == errno); + BX_CHECK(0 == result, "sem_wait failed. errno %d", errno); + return 0 == result; + } + + timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + ts.tv_sec += _msecs/1000; + ts.tv_nsec += (_msecs%1000)*1000; + return 0 == sem_timedwait(&m_handle, &ts); +# endif // BX_PLATFORM_ + } + + private: + sem_t m_handle; + }; +# endif // BX_CONFIG_SEMAPHORE_PTHREAD + +#elif BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 || BX_PLATFORM_WINRT + + class Semaphore + { + BX_CLASS(Semaphore + , NO_COPY + , NO_ASSIGNMENT + ); + + public: + Semaphore() + { +#if BX_PLATFORM_WINRT + m_handle = CreateSemaphoreEx(NULL, 0, LONG_MAX, NULL, 0, SEMAPHORE_ALL_ACCESS); +#else + m_handle = CreateSemaphore(NULL, 0, LONG_MAX, NULL); +#endif + BX_CHECK(NULL != m_handle, "Failed to create Semaphore!"); + } + + ~Semaphore() + { + CloseHandle(m_handle); + } + + void post(uint32_t _count = 1) const + { + ReleaseSemaphore(m_handle, _count, NULL); + } + + bool wait(int32_t _msecs = -1) const + { + DWORD milliseconds = (0 > _msecs) ? INFINITE : _msecs; +#if BX_PLATFORM_WINRT + return WAIT_OBJECT_0 == WaitForSingleObjectEx(m_handle, milliseconds, FALSE); +#else + return WAIT_OBJECT_0 == WaitForSingleObject(m_handle, milliseconds); +#endif + } + + private: + HANDLE m_handle; + }; + +#endif // BX_PLATFORM_ + +} // namespace bx + +#endif // BX_CONFIG_SUPPORTS_THREADING + +#endif // BX_SEM_H_HEADER_GUARD diff --git a/deps/include/bx/spscqueue.h b/deps/include/bx/spscqueue.h new file mode 100644 index 0000000..f2eed23 --- /dev/null +++ b/deps/include/bx/spscqueue.h @@ -0,0 +1,206 @@ +/* + * Copyright 2010-2015 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#ifndef BX_SPSCQUEUE_H_HEADER_GUARD +#define BX_SPSCQUEUE_H_HEADER_GUARD + +#include "bx.h" +#include "cpu.h" +#include "mutex.h" +#include "uint32_t.h" + +#include + +namespace bx +{ + // http://drdobbs.com/article/print?articleId=210604448&siteSectionName= + template + class SpScUnboundedQueueLf + { + BX_CLASS(SpScUnboundedQueueLf + , NO_COPY + , NO_ASSIGNMENT + ); + + public: + SpScUnboundedQueueLf() + : m_first(new Node(NULL) ) + , m_divider(m_first) + , m_last(m_first) + { + } + + ~SpScUnboundedQueueLf() + { + while (NULL != m_first) + { + Node* node = m_first; + m_first = node->m_next; + delete node; + } + } + + void push(Ty* _ptr) // producer only + { + m_last->m_next = new Node( (void*)_ptr); + atomicExchangePtr( (void**)&m_last, m_last->m_next); + while (m_first != m_divider) + { + Node* node = m_first; + m_first = m_first->m_next; + delete node; + } + } + + Ty* peek() // consumer only + { + if (m_divider != m_last) + { + Ty* ptr = (Ty*)m_divider->m_next->m_ptr; + return ptr; + } + + return NULL; + } + + Ty* pop() // consumer only + { + if (m_divider != m_last) + { + Ty* ptr = (Ty*)m_divider->m_next->m_ptr; + atomicExchangePtr( (void**)&m_divider, m_divider->m_next); + return ptr; + } + + return NULL; + } + + private: + struct Node + { + Node(void* _ptr) + : m_ptr(_ptr) + , m_next(NULL) + { + } + + void* m_ptr; + Node* m_next; + }; + + Node* m_first; + Node* m_divider; + Node* m_last; + }; + +#if BX_CONFIG_SUPPORTS_THREADING + template + class SpScUnboundedQueueMutex + { + BX_CLASS(SpScUnboundedQueueMutex + , NO_COPY + , NO_ASSIGNMENT + ); + + public: + SpScUnboundedQueueMutex() + { + } + + ~SpScUnboundedQueueMutex() + { + BX_CHECK(m_queue.empty(), "Queue is not empty!"); + } + + void push(Ty* _item) + { + bx::LwMutexScope lock(m_mutex); + m_queue.push_back(_item); + } + + Ty* peek() + { + bx::LwMutexScope lock(m_mutex); + if (!m_queue.empty() ) + { + return m_queue.front(); + } + + return NULL; + } + + Ty* pop() + { + bx::LwMutexScope lock(m_mutex); + if (!m_queue.empty() ) + { + Ty* item = m_queue.front(); + m_queue.pop_front(); + return item; + } + + return NULL; + } + + private: + bx::LwMutex m_mutex; + std::list m_queue; + }; +#endif // BX_CONFIG_SUPPORTS_THREADING + +#if BX_CONFIG_SPSCQUEUE_USE_MUTEX && BX_CONFIG_SUPPORTS_THREADING +# define SpScUnboundedQueue SpScUnboundedQueueMutex +#else +# define SpScUnboundedQueue SpScUnboundedQueueLf +#endif // BX_CONFIG_SPSCQUEUE_USE_MUTEX + +#if BX_CONFIG_SUPPORTS_THREADING + template + class SpScBlockingUnboundedQueue + { + BX_CLASS(SpScBlockingUnboundedQueue + , NO_COPY + , NO_ASSIGNMENT + ); + + public: + SpScBlockingUnboundedQueue() + { + } + + ~SpScBlockingUnboundedQueue() + { + } + + void push(Ty* _ptr) // producer only + { + m_queue.push( (void*)_ptr); + m_count.post(); + } + + Ty* peek() // consumer only + { + return (Ty*)m_queue.peek(); + } + + Ty* pop(int32_t _msecs = -1) // consumer only + { + if (m_count.wait(_msecs) ) + { + return (Ty*)m_queue.pop(); + } + + return NULL; + } + + private: + Semaphore m_count; + SpScUnboundedQueue m_queue; + }; +#endif // BX_CONFIG_SUPPORTS_THREADING + +} // namespace bx + +#endif // BX_SPSCQUEUE_H_HEADER_GUARD diff --git a/deps/include/bx/string.h b/deps/include/bx/string.h new file mode 100644 index 0000000..7f9224a --- /dev/null +++ b/deps/include/bx/string.h @@ -0,0 +1,506 @@ +/* + * Copyright 2010-2015 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#ifndef BX_STRING_H_HEADER_GUARD +#define BX_STRING_H_HEADER_GUARD + +#include "bx.h" +#include +#include // tolower +#include // va_list +#include // vsnprintf, vsnwprintf +#include +#include // wchar_t + +namespace bx +{ + /// + inline bool toBool(const char* _str) + { + char ch = (char)tolower(_str[0]); + return ch == 't' || ch == '1'; + } + + /// Case insensitive string compare. + inline int32_t stricmp(const char* _a, const char* _b) + { +#if BX_COMPILER_MSVC_COMPATIBLE + return _stricmp(_a, _b); +#else + return strcasecmp(_a, _b); +#endif // BX_COMPILER_ + } + + /// + inline size_t strnlen(const char* _str, size_t _max) + { + const char* end = _str + _max; + const char* ptr; + for (ptr = _str; ptr < end && *ptr != '\0'; ++ptr) {}; + return ptr - _str; + } + + /// Find substring in string. Limit search to _size. + inline const char* strnstr(const char* _str, const char* _find, size_t _size) + { + char first = *_find; + if ('\0' == first) + { + return _str; + } + + const char* cmp = _find + 1; + size_t len = strlen(cmp); + do + { + for (char match = *_str++; match != first && 0 < _size; match = *_str++, --_size) + { + if ('\0' == match) + { + return NULL; + } + } + + if (0 == _size) + { + return NULL; + } + + } while (0 != strncmp(_str, cmp, len) ); + + return --_str; + } + + /// Find substring in string. Case insensitive. + inline const char* stristr(const char* _str, const char* _find) + { + const char* ptr = _str; + + for (size_t len = strlen(_str), searchLen = strlen(_find) + ; len >= searchLen + ; ++ptr, --len) + { + // Find start of the string. + while (tolower(*ptr) != tolower(*_find) ) + { + ++ptr; + --len; + + // Search pattern lenght can't be longer than the string. + if (searchLen > len) + { + return NULL; + } + } + + // Set pointers. + const char* string = ptr; + const char* search = _find; + + // Start comparing. + while (tolower(*string++) == tolower(*search++) ) + { + // If end of the 'search' string is reached, all characters match. + if ('\0' == *search) + { + return ptr; + } + } + } + + return NULL; + } + + /// Find substring in string. Case insensitive. Limit search to _max. + inline const char* stristr(const char* _str, const char* _find, size_t _max) + { + const char* ptr = _str; + + size_t stringLen = strnlen(_str, _max); + const size_t findLen = strlen(_find); + + for (; stringLen >= findLen; ++ptr, --stringLen) + { + // Find start of the string. + while (tolower(*ptr) != tolower(*_find) ) + { + ++ptr; + --stringLen; + + // Search pattern lenght can't be longer than the string. + if (findLen > stringLen) + { + return NULL; + } + } + + // Set pointers. + const char* string = ptr; + const char* search = _find; + + // Start comparing. + while (tolower(*string++) == tolower(*search++) ) + { + // If end of the 'search' string is reached, all characters match. + if ('\0' == *search) + { + return ptr; + } + } + } + + return NULL; + } + + /// Find new line. Returns pointer after new line terminator. + inline const char* strnl(const char* _str) + { + for (; '\0' != *_str; _str += strnlen(_str, 1024) ) + { + const char* eol = strnstr(_str, "\r\n", 1024); + if (NULL != eol) + { + return eol + 2; + } + + eol = strnstr(_str, "\n", 1024); + if (NULL != eol) + { + return eol + 1; + } + } + + return _str; + } + + /// Find end of line. Retuns pointer to new line terminator. + inline const char* streol(const char* _str) + { + for (; '\0' != *_str; _str += strnlen(_str, 1024) ) + { + const char* eol = strnstr(_str, "\r\n", 1024); + if (NULL != eol) + { + return eol; + } + + eol = strnstr(_str, "\n", 1024); + if (NULL != eol) + { + return eol; + } + } + + return _str; + } + + /// Skip whitespace. + inline const char* strws(const char* _str) + { + for (; isspace(*_str); ++_str) {}; + return _str; + } + + /// Skip non-whitespace. + inline const char* strnws(const char* _str) + { + for (; !isspace(*_str); ++_str) {}; + return _str; + } + + /// Skip word. + inline const char* strword(const char* _str) + { + for (char ch = *_str++; isalnum(ch) || '_' == ch; ch = *_str++) {}; + return _str-1; + } + + /// Find matching block. + inline const char* strmb(const char* _str, char _open, char _close) + { + int count = 0; + for (char ch = *_str++; ch != '\0' && count >= 0; ch = *_str++) + { + if (ch == _open) + { + count++; + } + else if (ch == _close) + { + count--; + if (0 == count) + { + return _str-1; + } + } + } + + return NULL; + } + + // Normalize string to sane line endings. + inline void eolLF(char* _out, size_t _size, const char* _str) + { + if (0 < _size) + { + char* end = _out + _size - 1; + for (char ch = *_str++; ch != '\0' && _out < end; ch = *_str++) + { + if ('\r' != ch) + { + *_out++ = ch; + } + } + + *_out = '\0'; + } + } + + // Finds identifier. + inline const char* findIdentifierMatch(const char* _str, const char* _word) + { + size_t len = strlen(_word); + const char* ptr = strstr(_str, _word); + for (; NULL != ptr; ptr = strstr(ptr + len, _word) ) + { + if (ptr != _str) + { + char ch = *(ptr - 1); + if (isalnum(ch) || '_' == ch) + { + continue; + } + } + + char ch = ptr[len]; + if (isalnum(ch) || '_' == ch) + { + continue; + } + + return ptr; + } + + return ptr; + } + + // Finds any identifier from NULL terminated array of identifiers. + inline const char* findIdentifierMatch(const char* _str, const char* _words[]) + { + for (const char* word = *_words; NULL != word; ++_words, word = *_words) + { + const char* match = findIdentifierMatch(_str, word); + if (NULL != match) + { + return match; + } + } + + return NULL; + } + + /// Cross platform implementation of vsnprintf that returns number of + /// characters which would have been written to the final string if + /// enough space had been available. + inline int32_t vsnprintf(char* _str, size_t _count, const char* _format, va_list _argList) + { +#if BX_COMPILER_MSVC + int32_t len = ::vsnprintf_s(_str, _count, size_t(-1), _format, _argList); + return -1 == len ? ::_vscprintf(_format, _argList) : len; +#else + return ::vsnprintf(_str, _count, _format, _argList); +#endif // BX_COMPILER_MSVC + } + + /// Cross platform implementation of vsnwprintf that returns number of + /// characters which would have been written to the final string if + /// enough space had been available. + inline int32_t vsnwprintf(wchar_t* _str, size_t _count, const wchar_t* _format, va_list _argList) + { +#if BX_COMPILER_MSVC + int32_t len = ::_vsnwprintf_s(_str, _count, size_t(-1), _format, _argList); + return -1 == len ? ::_vscwprintf(_format, _argList) : len; +#elif defined(__MINGW32__) + return ::vsnwprintf(_str, _count, _format, _argList); +#else + return ::vswprintf(_str, _count, _format, _argList); +#endif // BX_COMPILER_MSVC + } + + /// + inline int32_t snprintf(char* _str, size_t _count, const char* _format, ...) // BX_PRINTF_ARGS(3, 4) + { + va_list argList; + va_start(argList, _format); + int32_t len = vsnprintf(_str, _count, _format, argList); + va_end(argList); + return len; + } + + /// + inline int32_t swnprintf(wchar_t* _out, size_t _count, const wchar_t* _format, ...) + { + va_list argList; + va_start(argList, _format); + int32_t len = vsnwprintf(_out, _count, _format, argList); + va_end(argList); + return len; + } + + /// + template + inline void stringPrintfVargs(Ty& _out, const char* _format, va_list _argList) + { + char temp[2048]; + + char* out = temp; + int32_t len = bx::vsnprintf(out, sizeof(temp), _format, _argList); + if ( (int32_t)sizeof(temp) < len) + { + out = (char*)alloca(len+1); + len = bx::vsnprintf(out, len, _format, _argList); + } + out[len] = '\0'; + _out.append(out); + } + + /// + template + inline void stringPrintf(Ty& _out, const char* _format, ...) + { + va_list argList; + va_start(argList, _format); + stringPrintfVargs(_out, _format, argList); + va_end(argList); + } + + /// Extract base file name from file path. + inline const char* baseName(const char* _filePath) + { + const char* bs = strrchr(_filePath, '\\'); + const char* fs = strrchr(_filePath, '/'); + const char* slash = (bs > fs ? bs : fs); + const char* colon = strrchr(_filePath, ':'); + const char* basename = slash > colon ? slash : colon; + if (NULL != basename) + { + return basename+1; + } + + return _filePath; + } + + /// Convert size in bytes to human readable string. + inline void prettify(char* _out, size_t _count, uint64_t _size) + { + uint8_t idx = 0; + double size = double(_size); + while (_size != (_size&0x7ff) + && idx < 9) + { + _size >>= 10; + size *= 1.0/1024.0; + ++idx; + } + + snprintf(_out, _count, "%0.2f %c%c", size, "BkMGTPEZY"[idx], idx > 0 ? 'B' : '\0'); + } + + /* + * Copyright (c) 1998 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + /// Copy src to string dst of size siz. At most siz-1 characters + /// will be copied. Always NUL terminates (unless siz == 0). + /// Returns strlen(src); if retval >= siz, truncation occurred. + inline size_t strlcpy(char* _dst, const char* _src, size_t _siz) + { + char* dd = _dst; + const char* ss = _src; + size_t nn = _siz; + + /* Copy as many bytes as will fit */ + if (nn != 0) + { + while (--nn != 0) + { + if ( (*dd++ = *ss++) == '\0') + { + break; + } + } + } + + /* Not enough room in dst, add NUL and traverse rest of src */ + if (nn == 0) + { + if (_siz != 0) + { + *dd = '\0'; /* NUL-terminate dst */ + } + + while (*ss++) + { + } + } + + return(ss - _src - 1); /* count does not include NUL */ + } + + /// Appends src to string dst of size siz (unlike strncat, siz is the + /// full size of dst, not space left). At most siz-1 characters + /// will be copied. Always NUL terminates (unless siz <= strlen(dst)). + /// Returns strlen(src) + MIN(siz, strlen(initial dst)). + /// If retval >= siz, truncation occurred. + inline size_t strlcat(char* _dst, const char* _src, size_t _siz) + { + char* dd = _dst; + const char *s = _src; + size_t nn = _siz; + size_t dlen; + + /* Find the end of dst and adjust bytes left but don't go past end */ + while (nn-- != 0 && *dd != '\0') + { + dd++; + } + + dlen = dd - _dst; + nn = _siz - dlen; + + if (nn == 0) + { + return(dlen + strlen(s)); + } + + while (*s != '\0') + { + if (nn != 1) + { + *dd++ = *s; + nn--; + } + s++; + } + *dd = '\0'; + + return(dlen + (s - _src)); /* count does not include NUL */ + } + +} // namespace bx + +#endif // BX_STRING_H_HEADER_GUARD diff --git a/deps/include/bx/thread.h b/deps/include/bx/thread.h new file mode 100644 index 0000000..31c9964 --- /dev/null +++ b/deps/include/bx/thread.h @@ -0,0 +1,262 @@ +/* + * Copyright 2010-2015 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#ifndef BX_THREAD_H_HEADER_GUARD +#define BX_THREAD_H_HEADER_GUARD + +#if BX_PLATFORM_POSIX +# include +#elif BX_PLATFORM_WINRT +using namespace Platform; +using namespace Windows::Foundation; +using namespace Windows::System::Threading; +#endif + +#include "sem.h" + +#if BX_CONFIG_SUPPORTS_THREADING + +namespace bx +{ + typedef int32_t (*ThreadFn)(void* _userData); + + class Thread + { + BX_CLASS(Thread + , NO_COPY + , NO_ASSIGNMENT + ); + + public: + Thread() +#if BX_PLATFORM_WINDOWS|BX_PLATFORM_XBOX360|BX_PLATFORM_WINRT + : m_handle(INVALID_HANDLE_VALUE) +#elif BX_PLATFORM_POSIX + : m_handle(0) +#endif // BX_PLATFORM_ + , m_fn(NULL) + , m_userData(NULL) + , m_stackSize(0) + , m_exitCode(0 /*EXIT_SUCCESS*/) + , m_running(false) + { + } + + virtual ~Thread() + { + if (m_running) + { + shutdown(); + } + } + + void init(ThreadFn _fn, void* _userData = NULL, uint32_t _stackSize = 0) + { + BX_CHECK(!m_running, "Already running!"); + + m_fn = _fn; + m_userData = _userData; + m_stackSize = _stackSize; + m_running = true; + +#if BX_PLATFORM_WINDOWS|BX_PLATFORM_XBOX360 + m_handle = CreateThread(NULL + , m_stackSize + , threadFunc + , this + , 0 + , NULL + ); +#elif BX_PLATFORM_WINRT + m_handle = CreateEventEx(nullptr, nullptr, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS); + auto workItemHandler = ref new WorkItemHandler([=](IAsyncAction^) + { + m_exitCode = threadFunc(this); + SetEvent(m_handle); + }, CallbackContext::Any); + + ThreadPool::RunAsync(workItemHandler, WorkItemPriority::Normal, WorkItemOptions::TimeSliced); +#elif BX_PLATFORM_POSIX + int result; + BX_UNUSED(result); + + pthread_attr_t attr; + result = pthread_attr_init(&attr); + BX_CHECK(0 == result, "pthread_attr_init failed! %d", result); + + if (0 != m_stackSize) + { + result = pthread_attr_setstacksize(&attr, m_stackSize); + BX_CHECK(0 == result, "pthread_attr_setstacksize failed! %d", result); + } + +// sched_param sched; +// sched.sched_priority = 0; +// result = pthread_attr_setschedparam(&attr, &sched); +// BX_CHECK(0 == result, "pthread_attr_setschedparam failed! %d", result); + + result = pthread_create(&m_handle, &attr, &threadFunc, this); + BX_CHECK(0 == result, "pthread_attr_setschedparam failed! %d", result); +#endif // BX_PLATFORM_ + + m_sem.wait(); + } + + void shutdown() + { + BX_CHECK(m_running, "Not running!"); +#if BX_PLATFORM_WINDOWS|BX_PLATFORM_XBOX360 + WaitForSingleObject(m_handle, INFINITE); + GetExitCodeThread(m_handle, (DWORD*)&m_exitCode); + CloseHandle(m_handle); + m_handle = INVALID_HANDLE_VALUE; +#elif BX_PLATFORM_WINRT + WaitForSingleObjectEx(m_handle, INFINITE, FALSE); + CloseHandle(m_handle); + m_handle = INVALID_HANDLE_VALUE; +#elif BX_PLATFORM_POSIX + union + { + void* ptr; + int32_t i; + } cast; + pthread_join(m_handle, &cast.ptr); + m_exitCode = cast.i; + m_handle = 0; +#endif // BX_PLATFORM_ + m_running = false; + } + + bool isRunning() const + { + return m_running; + } + + int32_t getExitCode() const + { + return m_exitCode; + } + + void setThreadName(const char* _name) + { +#if BX_PLATFORM_OSX|BX_PLATFORM_IOS + pthread_setname_np(_name); +#elif BX_PLATFORM_POSIX + pthread_setname_np(m_handle, _name); +#else + BX_UNUSED(_name); +#endif // BX_PLATFORM_ + } + + private: + int32_t entry() + { + m_sem.post(); + return m_fn(m_userData); + } + +#if BX_PLATFORM_WINDOWS|BX_PLATFORM_XBOX360|BX_PLATFORM_WINRT + static DWORD WINAPI threadFunc(LPVOID _arg) + { + Thread* thread = (Thread*)_arg; + int32_t result = thread->entry(); + return result; + } +#else + static void* threadFunc(void* _arg) + { + Thread* thread = (Thread*)_arg; + union + { + void* ptr; + int32_t i; + } cast; + cast.i = thread->entry(); + return cast.ptr; + } +#endif // BX_PLATFORM_ + +#if BX_PLATFORM_WINDOWS|BX_PLATFORM_XBOX360|BX_PLATFORM_WINRT + HANDLE m_handle; +#elif BX_PLATFORM_POSIX + pthread_t m_handle; +#endif // BX_PLATFORM_ + + ThreadFn m_fn; + void* m_userData; + Semaphore m_sem; + uint32_t m_stackSize; + int32_t m_exitCode; + bool m_running; + }; + +#if BX_PLATFORM_WINDOWS + class TlsData + { + public: + TlsData() + { + m_id = TlsAlloc(); + BX_CHECK(TLS_OUT_OF_INDEXES != m_id, "Failed to allocated TLS index (err: 0x%08x).", GetLastError() ); + } + + ~TlsData() + { + BOOL result = TlsFree(m_id); + BX_CHECK(0 != result, "Failed to free TLS index (err: 0x%08x).", GetLastError() ); BX_UNUSED(result); + } + + void* get() const + { + return TlsGetValue(m_id); + } + + void set(void* _ptr) + { + TlsSetValue(m_id, _ptr); + } + + private: + uint32_t m_id; + }; + +#elif !(BX_PLATFORM_WINRT) + + class TlsData + { + public: + TlsData() + { + int result = pthread_key_create(&m_id, NULL); + BX_CHECK(0 == result, "pthread_key_create failed %d.", result); BX_UNUSED(result); + } + + ~TlsData() + { + int result = pthread_key_delete(m_id); + BX_CHECK(0 == result, "pthread_key_delete failed %d.", result); BX_UNUSED(result); + } + + void* get() const + { + return pthread_getspecific(m_id); + } + + void set(void* _ptr) + { + int result = pthread_setspecific(m_id, _ptr); + BX_CHECK(0 == result, "pthread_setspecific failed %d.", result); BX_UNUSED(result); + } + + private: + pthread_key_t m_id; + }; +#endif // BX_PLATFORM_WINDOWS + +} // namespace bx + +#endif // BX_CONFIG_SUPPORTS_THREADING + +#endif // BX_THREAD_H_HEADER_GUARD diff --git a/deps/include/bx/timer.h b/deps/include/bx/timer.h new file mode 100644 index 0000000..7d4657f --- /dev/null +++ b/deps/include/bx/timer.h @@ -0,0 +1,62 @@ +/* + * Copyright 2010-2015 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#ifndef BX_TIMER_H_HEADER_GUARD +#define BX_TIMER_H_HEADER_GUARD + +#include "bx.h" + +#if BX_PLATFORM_ANDROID +# include // clock, clock_gettime +#elif BX_PLATFORM_EMSCRIPTEN +# include +#elif BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT +# include +#else +# include // gettimeofday +#endif // BX_PLATFORM_ + +namespace bx +{ + inline int64_t getHPCounter() + { +#if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 || BX_PLATFORM_WINRT + LARGE_INTEGER li; + // Performance counter value may unexpectedly leap forward + // http://support.microsoft.com/kb/274323 + QueryPerformanceCounter(&li); + int64_t i64 = li.QuadPart; +#elif BX_PLATFORM_ANDROID + struct timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); + int64_t i64 = now.tv_sec*INT64_C(1000000000) + now.tv_nsec; +#elif BX_PLATFORM_EMSCRIPTEN + int64_t i64 = int64_t(1000.0f * emscripten_get_now() ); +#else + struct timeval now; + gettimeofday(&now, 0); + int64_t i64 = now.tv_sec*INT64_C(1000000) + now.tv_usec; +#endif // BX_PLATFORM_ + return i64; + } + + inline int64_t getHPFrequency() + { +#if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 || BX_PLATFORM_WINRT + LARGE_INTEGER li; + QueryPerformanceFrequency(&li); + return li.QuadPart; +#elif BX_PLATFORM_ANDROID + return INT64_C(1000000000); +#elif BX_PLATFORM_EMSCRIPTEN + return INT64_C(1000000); +#else + return INT64_C(1000000); +#endif // BX_PLATFORM_ + } + +} // namespace bx + +#endif // BX_TIMER_H_HEADER_GUARD diff --git a/deps/include/bx/tokenizecmd.h b/deps/include/bx/tokenizecmd.h new file mode 100644 index 0000000..554fcd5 --- /dev/null +++ b/deps/include/bx/tokenizecmd.h @@ -0,0 +1,146 @@ +/* + * Copyright 2012-2015 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#ifndef BX_TOKENIZE_CMD_H_HEADER_GUARD +#define BX_TOKENIZE_CMD_H_HEADER_GUARD + +#include +#include +#include + +namespace bx +{ + // Reference: + // http://msdn.microsoft.com/en-us/library/a1y7w461.aspx + static inline const char* tokenizeCommandLine(const char* _commandLine, char* _buffer, uint32_t& _bufferSize, int& _argc, char* _argv[], int _maxArgvs, char _term = '\0') + { + int argc = 0; + const char* curr = _commandLine; + char* currOut = _buffer; + char term = ' '; + bool sub = false; + + enum ParserState + { + SkipWhitespace, + SetTerm, + Copy, + Escape, + End, + }; + + ParserState state = SkipWhitespace; + + while ('\0' != *curr + && _term != *curr + && argc < _maxArgvs) + { + switch (state) + { + case SkipWhitespace: + for (; isspace(*curr); ++curr) {}; // skip whitespace + state = SetTerm; + break; + + case SetTerm: + if ('"' == *curr) + { + term = '"'; + ++curr; // skip begining quote + } + else + { + term = ' '; + } + + _argv[argc] = currOut; + ++argc; + + state = Copy; + break; + + case Copy: + if ('\\' == *curr) + { + state = Escape; + } + else if ('"' == *curr + && '"' != term) + { + sub = !sub; + } + else if (isspace(*curr) && !sub) + { + state = End; + } + else if (term != *curr || sub) + { + *currOut = *curr; + ++currOut; + } + else + { + state = End; + } + ++curr; + break; + + case Escape: + { + const char* start = --curr; + for (; '\\' == *curr; ++curr) {}; + + if ('"' != *curr) + { + int count = (int)(curr-start); + + curr = start; + for (int ii = 0; ii < count; ++ii) + { + *currOut = *curr; + ++currOut; + ++curr; + } + } + else + { + curr = start+1; + *currOut = *curr; + ++currOut; + ++curr; + } + } + state = Copy; + break; + + case End: + *currOut = '\0'; + ++currOut; + state = SkipWhitespace; + break; + } + } + + *currOut = '\0'; + if (0 < argc + && '\0' == _argv[argc-1][0]) + { + --argc; + } + + _bufferSize = (uint32_t)(currOut - _buffer); + _argc = argc; + + if ('\0' != *curr) + { + ++curr; + } + + return curr; + } + +} // namespace bx + +#endif // TOKENIZE_CMD_H_HEADER_GUARD diff --git a/deps/include/bx/uint32_t.h b/deps/include/bx/uint32_t.h new file mode 100644 index 0000000..22eed28 --- /dev/null +++ b/deps/include/bx/uint32_t.h @@ -0,0 +1,755 @@ +/* + * Copyright 2010-2015 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +// Copyright 2006 Mike Acton +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE + +#ifndef BX_UINT32_T_H_HEADER_GUARD +#define BX_UINT32_T_H_HEADER_GUARD + +#include "bx.h" + +#if BX_COMPILER_MSVC +# if BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT +# include // math.h is included because VS bitches: + // warning C4985: 'ceil': attributes not present on previous declaration. + // must be included before intrin.h. +# include +# pragma intrinsic(_BitScanForward) +# pragma intrinsic(_BitScanReverse) +# if BX_ARCH_64BIT +# pragma intrinsic(_BitScanForward64) +# pragma intrinsic(_BitScanReverse64) +# endif // BX_ARCH_64BIT +# endif // BX_PLATFORM_WINDOWS +#endif // BX_COMPILER_MSVC + +#define BX_HALF_FLOAT_ZERO UINT16_C(0) +#define BX_HALF_FLOAT_HALF UINT16_C(0x3800) +#define BX_HALF_FLOAT_ONE UINT16_C(0x3c00) +#define BX_HALF_FLOAT_TWO UINT16_C(0x4000) + +namespace bx +{ + inline uint32_t uint32_li(uint32_t _a) + { + return _a; + } + + inline uint32_t uint32_dec(uint32_t _a) + { + return _a - 1; + } + + inline uint32_t uint32_inc(uint32_t _a) + { + return _a + 1; + } + + inline uint32_t uint32_not(uint32_t _a) + { + return ~_a; + } + + inline uint32_t uint32_neg(uint32_t _a) + { + return -(int32_t)_a; + } + + inline uint32_t uint32_ext(uint32_t _a) + { + return ( (int32_t)_a)>>31; + } + + inline uint32_t uint32_and(uint32_t _a, uint32_t _b) + { + return _a & _b; + } + + inline uint32_t uint32_andc(uint32_t _a, uint32_t _b) + { + return _a & ~_b; + } + + inline uint32_t uint32_xor(uint32_t _a, uint32_t _b) + { + return _a ^ _b; + } + + inline uint32_t uint32_xorl(uint32_t _a, uint32_t _b) + { + return !_a != !_b; + } + + inline uint32_t uint32_or(uint32_t _a, uint32_t _b) + { + return _a | _b; + } + + inline uint32_t uint32_orc(uint32_t _a, uint32_t _b) + { + return _a | ~_b; + } + + inline uint32_t uint32_sll(uint32_t _a, int _sa) + { + return _a << _sa; + } + + inline uint32_t uint32_srl(uint32_t _a, int _sa) + { + return _a >> _sa; + } + + inline uint32_t uint32_sra(uint32_t _a, int _sa) + { + return ( (int32_t)_a) >> _sa; + } + + inline uint32_t uint32_rol(uint32_t _a, int _sa) + { + return ( _a << _sa) | (_a >> (32-_sa) ); + } + + inline uint32_t uint32_ror(uint32_t _a, int _sa) + { + return ( _a >> _sa) | (_a << (32-_sa) ); + } + + inline uint32_t uint32_add(uint32_t _a, uint32_t _b) + { + return _a + _b; + } + + inline uint32_t uint32_sub(uint32_t _a, uint32_t _b) + { + return _a - _b; + } + + inline uint32_t uint32_mul(uint32_t _a, uint32_t _b) + { + return _a * _b; + } + + inline uint32_t uint32_div(uint32_t _a, uint32_t _b) + { + return (_a / _b); + } + + inline uint32_t uint32_mod(uint32_t _a, uint32_t _b) + { + return (_a % _b); + } + + inline uint32_t uint32_cmpeq(uint32_t _a, uint32_t _b) + { + return -(_a == _b); + } + + inline uint32_t uint32_cmpneq(uint32_t _a, uint32_t _b) + { + return -(_a != _b); + } + + inline uint32_t uint32_cmplt(uint32_t _a, uint32_t _b) + { + return -(_a < _b); + } + + inline uint32_t uint32_cmple(uint32_t _a, uint32_t _b) + { + return -(_a <= _b); + } + + inline uint32_t uint32_cmpgt(uint32_t _a, uint32_t _b) + { + return -(_a > _b); + } + + inline uint32_t uint32_cmpge(uint32_t _a, uint32_t _b) + { + return -(_a >= _b); + } + + inline uint32_t uint32_setnz(uint32_t _a) + { + return -!!_a; + } + + inline uint32_t uint32_satadd(uint32_t _a, uint32_t _b) + { + const uint32_t add = uint32_add(_a, _b); + const uint32_t lt = uint32_cmplt(add, _a); + const uint32_t result = uint32_or(add, lt); + + return result; + } + + inline uint32_t uint32_satsub(uint32_t _a, uint32_t _b) + { + const uint32_t sub = uint32_sub(_a, _b); + const uint32_t le = uint32_cmple(sub, _a); + const uint32_t result = uint32_and(sub, le); + + return result; + } + + inline uint32_t uint32_satmul(uint32_t _a, uint32_t _b) + { + const uint64_t mul = (uint64_t)_a * (uint64_t)_b; + const uint32_t hi = mul >> 32; + const uint32_t nz = uint32_setnz(hi); + const uint32_t result = uint32_or(uint32_t(mul), nz); + + return result; + } + + inline uint32_t uint32_sels(uint32_t test, uint32_t _a, uint32_t _b) + { + const uint32_t mask = uint32_ext(test); + const uint32_t sel_a = uint32_and(_a, mask); + const uint32_t sel_b = uint32_andc(_b, mask); + const uint32_t result = uint32_or(sel_a, sel_b); + + return (result); + } + + inline uint32_t uint32_selb(uint32_t _mask, uint32_t _a, uint32_t _b) + { + const uint32_t sel_a = uint32_and(_a, _mask); + const uint32_t sel_b = uint32_andc(_b, _mask); + const uint32_t result = uint32_or(sel_a, sel_b); + + return (result); + } + + inline uint32_t uint32_imin(uint32_t _a, uint32_t _b) + { + const uint32_t a_sub_b = uint32_sub(_a, _b); + const uint32_t result = uint32_sels(a_sub_b, _a, _b); + + return result; + } + + inline uint32_t uint32_imax(uint32_t _a, uint32_t _b) + { + const uint32_t b_sub_a = uint32_sub(_b, _a); + const uint32_t result = uint32_sels(b_sub_a, _a, _b); + + return result; + } + + inline uint32_t uint32_min(uint32_t _a, uint32_t _b) + { + return _a > _b ? _b : _a; + } + + inline uint32_t uint32_max(uint32_t _a, uint32_t _b) + { + return _a > _b ? _a : _b; + } + + inline uint32_t uint32_clamp(uint32_t _a, uint32_t _min, uint32_t _max) + { + const uint32_t tmp = uint32_max(_a, _min); + const uint32_t result = uint32_min(tmp, _max); + + return result; + } + + inline uint32_t uint32_iclamp(uint32_t _a, uint32_t _min, uint32_t _max) + { + const uint32_t tmp = uint32_imax(_a, _min); + const uint32_t result = uint32_imin(tmp, _max); + + return result; + } + + inline uint32_t uint32_incwrap(uint32_t _val, uint32_t _min, uint32_t _max) + { + const uint32_t inc = uint32_inc(_val); + const uint32_t max_diff = uint32_sub(_max, _val); + const uint32_t neg_max_diff = uint32_neg(max_diff); + const uint32_t max_or = uint32_or(max_diff, neg_max_diff); + const uint32_t max_diff_nz = uint32_ext(max_or); + const uint32_t result = uint32_selb(max_diff_nz, inc, _min); + + return result; + } + + inline uint32_t uint32_decwrap(uint32_t _val, uint32_t _min, uint32_t _max) + { + const uint32_t dec = uint32_dec(_val); + const uint32_t min_diff = uint32_sub(_min, _val); + const uint32_t neg_min_diff = uint32_neg(min_diff); + const uint32_t min_or = uint32_or(min_diff, neg_min_diff); + const uint32_t min_diff_nz = uint32_ext(min_or); + const uint32_t result = uint32_selb(min_diff_nz, dec, _max); + + return result; + } + + inline uint32_t uint32_cntbits_ref(uint32_t _val) + { + const uint32_t tmp0 = uint32_srl(_val, 1); + const uint32_t tmp1 = uint32_and(tmp0, 0x55555555); + const uint32_t tmp2 = uint32_sub(_val, tmp1); + const uint32_t tmp3 = uint32_and(tmp2, 0xc30c30c3); + const uint32_t tmp4 = uint32_srl(tmp2, 2); + const uint32_t tmp5 = uint32_and(tmp4, 0xc30c30c3); + const uint32_t tmp6 = uint32_srl(tmp2, 4); + const uint32_t tmp7 = uint32_and(tmp6, 0xc30c30c3); + const uint32_t tmp8 = uint32_add(tmp3, tmp5); + const uint32_t tmp9 = uint32_add(tmp7, tmp8); + const uint32_t tmpA = uint32_srl(tmp9, 6); + const uint32_t tmpB = uint32_add(tmp9, tmpA); + const uint32_t tmpC = uint32_srl(tmpB, 12); + const uint32_t tmpD = uint32_srl(tmpB, 24); + const uint32_t tmpE = uint32_add(tmpB, tmpC); + const uint32_t tmpF = uint32_add(tmpD, tmpE); + const uint32_t result = uint32_and(tmpF, 0x3f); + + return result; + } + + /// Count number of bits set. + inline uint32_t uint32_cntbits(uint32_t _val) + { +#if BX_COMPILER_GCC || BX_COMPILER_CLANG + return __builtin_popcount(_val); +#elif BX_COMPILER_MSVC && BX_PLATFORM_WINDOWS + return __popcnt(_val); +#else + return uint32_cntbits_ref(_val); +#endif // BX_COMPILER_ + } + + inline uint32_t uint32_cntlz_ref(uint32_t _val) + { + const uint32_t tmp0 = uint32_srl(_val, 1); + const uint32_t tmp1 = uint32_or(tmp0, _val); + const uint32_t tmp2 = uint32_srl(tmp1, 2); + const uint32_t tmp3 = uint32_or(tmp2, tmp1); + const uint32_t tmp4 = uint32_srl(tmp3, 4); + const uint32_t tmp5 = uint32_or(tmp4, tmp3); + const uint32_t tmp6 = uint32_srl(tmp5, 8); + const uint32_t tmp7 = uint32_or(tmp6, tmp5); + const uint32_t tmp8 = uint32_srl(tmp7, 16); + const uint32_t tmp9 = uint32_or(tmp8, tmp7); + const uint32_t tmpA = uint32_not(tmp9); + const uint32_t result = uint32_cntbits(tmpA); + + return result; + } + + /// Count number of leading zeros. + inline uint32_t uint32_cntlz(uint32_t _val) + { +#if BX_COMPILER_GCC || BX_COMPILER_CLANG + return __builtin_clz(_val); +#elif BX_COMPILER_MSVC && BX_PLATFORM_WINDOWS + unsigned long index; + _BitScanReverse(&index, _val); + return 31 - index; +#else + return uint32_cntlz_ref(_val); +#endif // BX_COMPILER_ + } + + inline uint32_t uint32_cnttz_ref(uint32_t _val) + { + const uint32_t tmp0 = uint32_not(_val); + const uint32_t tmp1 = uint32_dec(_val); + const uint32_t tmp2 = uint32_and(tmp0, tmp1); + const uint32_t result = uint32_cntbits(tmp2); + + return result; + } + + inline uint32_t uint32_cnttz(uint32_t _val) + { +#if BX_COMPILER_GCC || BX_COMPILER_CLANG + return __builtin_ctz(_val); +#elif BX_COMPILER_MSVC && BX_PLATFORM_WINDOWS + unsigned long index; + _BitScanForward(&index, _val); + return index; +#else + return uint32_cnttz_ref(_val); +#endif // BX_COMPILER_ + } + + // shuffle: + // ---- ---- ---- ---- fedc ba98 7654 3210 + // to: + // -f-e -d-c -b-a -9-8 -7-6 -5-4 -3-2 -1-0 + inline uint32_t uint32_part1by1(uint32_t _a) + { + const uint32_t val = uint32_and(_a, 0xffff); + + const uint32_t tmp0 = uint32_sll(val, 8); + const uint32_t tmp1 = uint32_xor(val, tmp0); + const uint32_t tmp2 = uint32_and(tmp1, 0x00ff00ff); + + const uint32_t tmp3 = uint32_sll(tmp2, 4); + const uint32_t tmp4 = uint32_xor(tmp2, tmp3); + const uint32_t tmp5 = uint32_and(tmp4, 0x0f0f0f0f); + + const uint32_t tmp6 = uint32_sll(tmp5, 2); + const uint32_t tmp7 = uint32_xor(tmp5, tmp6); + const uint32_t tmp8 = uint32_and(tmp7, 0x33333333); + + const uint32_t tmp9 = uint32_sll(tmp8, 1); + const uint32_t tmpA = uint32_xor(tmp8, tmp9); + const uint32_t result = uint32_and(tmpA, 0x55555555); + + return result; + } + + // shuffle: + // ---- ---- ---- ---- ---- --98 7654 3210 + // to: + // ---- 9--8 --7- -6-- 5--4 --3- -2-- 1--0 + inline uint32_t uint32_part1by2(uint32_t _a) + { + const uint32_t val = uint32_and(_a, 0x3ff); + + const uint32_t tmp0 = uint32_sll(val, 16); + const uint32_t tmp1 = uint32_xor(val, tmp0); + const uint32_t tmp2 = uint32_and(tmp1, 0xff0000ff); + + const uint32_t tmp3 = uint32_sll(tmp2, 8); + const uint32_t tmp4 = uint32_xor(tmp2, tmp3); + const uint32_t tmp5 = uint32_and(tmp4, 0x0300f00f); + + const uint32_t tmp6 = uint32_sll(tmp5, 4); + const uint32_t tmp7 = uint32_xor(tmp5, tmp6); + const uint32_t tmp8 = uint32_and(tmp7, 0x030c30c3); + + const uint32_t tmp9 = uint32_sll(tmp8, 2); + const uint32_t tmpA = uint32_xor(tmp8, tmp9); + const uint32_t result = uint32_and(tmpA, 0x09249249); + + return result; + } + + inline uint32_t uint32_testpow2(uint32_t _a) + { + const uint32_t tmp0 = uint32_not(_a); + const uint32_t tmp1 = uint32_inc(tmp0); + const uint32_t tmp2 = uint32_and(_a, tmp1); + const uint32_t tmp3 = uint32_cmpeq(tmp2, _a); + const uint32_t tmp4 = uint32_cmpneq(_a, 0); + const uint32_t result = uint32_and(tmp3, tmp4); + + return result; + } + + inline uint32_t uint32_nextpow2(uint32_t _a) + { + const uint32_t tmp0 = uint32_dec(_a); + const uint32_t tmp1 = uint32_srl(tmp0, 1); + const uint32_t tmp2 = uint32_or(tmp0, tmp1); + const uint32_t tmp3 = uint32_srl(tmp2, 2); + const uint32_t tmp4 = uint32_or(tmp2, tmp3); + const uint32_t tmp5 = uint32_srl(tmp4, 4); + const uint32_t tmp6 = uint32_or(tmp4, tmp5); + const uint32_t tmp7 = uint32_srl(tmp6, 8); + const uint32_t tmp8 = uint32_or(tmp6, tmp7); + const uint32_t tmp9 = uint32_srl(tmp8, 16); + const uint32_t tmpA = uint32_or(tmp8, tmp9); + const uint32_t result = uint32_inc(tmpA); + + return result; + } + + inline uint16_t halfFromFloat(float _a) + { + union { uint32_t ui; float flt; } ftou; + ftou.flt = _a; + + const uint32_t one = uint32_li(0x00000001); + const uint32_t f_s_mask = uint32_li(0x80000000); + const uint32_t f_e_mask = uint32_li(0x7f800000); + const uint32_t f_m_mask = uint32_li(0x007fffff); + const uint32_t f_m_hidden_bit = uint32_li(0x00800000); + const uint32_t f_m_round_bit = uint32_li(0x00001000); + const uint32_t f_snan_mask = uint32_li(0x7fc00000); + const uint32_t f_e_pos = uint32_li(0x00000017); + const uint32_t h_e_pos = uint32_li(0x0000000a); + const uint32_t h_e_mask = uint32_li(0x00007c00); + const uint32_t h_snan_mask = uint32_li(0x00007e00); + const uint32_t h_e_mask_value = uint32_li(0x0000001f); + const uint32_t f_h_s_pos_offset = uint32_li(0x00000010); + const uint32_t f_h_bias_offset = uint32_li(0x00000070); + const uint32_t f_h_m_pos_offset = uint32_li(0x0000000d); + const uint32_t h_nan_min = uint32_li(0x00007c01); + const uint32_t f_h_e_biased_flag = uint32_li(0x0000008f); + const uint32_t f_s = uint32_and(ftou.ui, f_s_mask); + const uint32_t f_e = uint32_and(ftou.ui, f_e_mask); + const uint16_t h_s = (uint16_t)uint32_srl(f_s, f_h_s_pos_offset); + const uint32_t f_m = uint32_and(ftou.ui, f_m_mask); + const uint16_t f_e_amount = (uint16_t)uint32_srl(f_e, f_e_pos); + const uint32_t f_e_half_bias = uint32_sub(f_e_amount, f_h_bias_offset); + const uint32_t f_snan = uint32_and(ftou.ui, f_snan_mask); + const uint32_t f_m_round_mask = uint32_and(f_m, f_m_round_bit); + const uint32_t f_m_round_offset = uint32_sll(f_m_round_mask, one); + const uint32_t f_m_rounded = uint32_add(f_m, f_m_round_offset); + const uint32_t f_m_denorm_sa = uint32_sub(one, f_e_half_bias); + const uint32_t f_m_with_hidden = uint32_or(f_m_rounded, f_m_hidden_bit); + const uint32_t f_m_denorm = uint32_srl(f_m_with_hidden, f_m_denorm_sa); + const uint32_t h_m_denorm = uint32_srl(f_m_denorm, f_h_m_pos_offset); + const uint32_t f_m_rounded_overflow = uint32_and(f_m_rounded, f_m_hidden_bit); + const uint32_t m_nan = uint32_srl(f_m, f_h_m_pos_offset); + const uint32_t h_em_nan = uint32_or(h_e_mask, m_nan); + const uint32_t h_e_norm_overflow_offset = uint32_inc(f_e_half_bias); + const uint32_t h_e_norm_overflow = uint32_sll(h_e_norm_overflow_offset, h_e_pos); + const uint32_t h_e_norm = uint32_sll(f_e_half_bias, h_e_pos); + const uint32_t h_m_norm = uint32_srl(f_m_rounded, f_h_m_pos_offset); + const uint32_t h_em_norm = uint32_or(h_e_norm, h_m_norm); + const uint32_t is_h_ndenorm_msb = uint32_sub(f_h_bias_offset, f_e_amount); + const uint32_t is_f_e_flagged_msb = uint32_sub(f_h_e_biased_flag, f_e_half_bias); + const uint32_t is_h_denorm_msb = uint32_not(is_h_ndenorm_msb); + const uint32_t is_f_m_eqz_msb = uint32_dec(f_m); + const uint32_t is_h_nan_eqz_msb = uint32_dec(m_nan); + const uint32_t is_f_inf_msb = uint32_and(is_f_e_flagged_msb, is_f_m_eqz_msb); + const uint32_t is_f_nan_underflow_msb = uint32_and(is_f_e_flagged_msb, is_h_nan_eqz_msb); + const uint32_t is_e_overflow_msb = uint32_sub(h_e_mask_value, f_e_half_bias); + const uint32_t is_h_inf_msb = uint32_or(is_e_overflow_msb, is_f_inf_msb); + const uint32_t is_f_nsnan_msb = uint32_sub(f_snan, f_snan_mask); + const uint32_t is_m_norm_overflow_msb = uint32_neg(f_m_rounded_overflow); + const uint32_t is_f_snan_msb = uint32_not(is_f_nsnan_msb); + const uint32_t h_em_overflow_result = uint32_sels(is_m_norm_overflow_msb, h_e_norm_overflow, h_em_norm); + const uint32_t h_em_nan_result = uint32_sels(is_f_e_flagged_msb, h_em_nan, h_em_overflow_result); + const uint32_t h_em_nan_underflow_result = uint32_sels(is_f_nan_underflow_msb, h_nan_min, h_em_nan_result); + const uint32_t h_em_inf_result = uint32_sels(is_h_inf_msb, h_e_mask, h_em_nan_underflow_result); + const uint32_t h_em_denorm_result = uint32_sels(is_h_denorm_msb, h_m_denorm, h_em_inf_result); + const uint32_t h_em_snan_result = uint32_sels(is_f_snan_msb, h_snan_mask, h_em_denorm_result); + const uint32_t h_result = uint32_or(h_s, h_em_snan_result); + + return (uint16_t)(h_result); + } + + inline float halfToFloat(uint16_t _a) + { + const uint32_t h_e_mask = uint32_li(0x00007c00); + const uint32_t h_m_mask = uint32_li(0x000003ff); + const uint32_t h_s_mask = uint32_li(0x00008000); + const uint32_t h_f_s_pos_offset = uint32_li(0x00000010); + const uint32_t h_f_e_pos_offset = uint32_li(0x0000000d); + const uint32_t h_f_bias_offset = uint32_li(0x0001c000); + const uint32_t f_e_mask = uint32_li(0x7f800000); + const uint32_t f_m_mask = uint32_li(0x007fffff); + const uint32_t h_f_e_denorm_bias = uint32_li(0x0000007e); + const uint32_t h_f_m_denorm_sa_bias = uint32_li(0x00000008); + const uint32_t f_e_pos = uint32_li(0x00000017); + const uint32_t h_e_mask_minus_one = uint32_li(0x00007bff); + const uint32_t h_e = uint32_and(_a, h_e_mask); + const uint32_t h_m = uint32_and(_a, h_m_mask); + const uint32_t h_s = uint32_and(_a, h_s_mask); + const uint32_t h_e_f_bias = uint32_add(h_e, h_f_bias_offset); + const uint32_t h_m_nlz = uint32_cntlz(h_m); + const uint32_t f_s = uint32_sll(h_s, h_f_s_pos_offset); + const uint32_t f_e = uint32_sll(h_e_f_bias, h_f_e_pos_offset); + const uint32_t f_m = uint32_sll(h_m, h_f_e_pos_offset); + const uint32_t f_em = uint32_or(f_e, f_m); + const uint32_t h_f_m_sa = uint32_sub(h_m_nlz, h_f_m_denorm_sa_bias); + const uint32_t f_e_denorm_unpacked = uint32_sub(h_f_e_denorm_bias, h_f_m_sa); + const uint32_t h_f_m = uint32_sll(h_m, h_f_m_sa); + const uint32_t f_m_denorm = uint32_and(h_f_m, f_m_mask); + const uint32_t f_e_denorm = uint32_sll(f_e_denorm_unpacked, f_e_pos); + const uint32_t f_em_denorm = uint32_or(f_e_denorm, f_m_denorm); + const uint32_t f_em_nan = uint32_or(f_e_mask, f_m); + const uint32_t is_e_eqz_msb = uint32_dec(h_e); + const uint32_t is_m_nez_msb = uint32_neg(h_m); + const uint32_t is_e_flagged_msb = uint32_sub(h_e_mask_minus_one, h_e); + const uint32_t is_zero_msb = uint32_andc(is_e_eqz_msb, is_m_nez_msb); + const uint32_t is_inf_msb = uint32_andc(is_e_flagged_msb, is_m_nez_msb); + const uint32_t is_denorm_msb = uint32_and(is_m_nez_msb, is_e_eqz_msb); + const uint32_t is_nan_msb = uint32_and(is_e_flagged_msb, is_m_nez_msb); + const uint32_t is_zero = uint32_ext(is_zero_msb); + const uint32_t f_zero_result = uint32_andc(f_em, is_zero); + const uint32_t f_denorm_result = uint32_sels(is_denorm_msb, f_em_denorm, f_zero_result); + const uint32_t f_inf_result = uint32_sels(is_inf_msb, f_e_mask, f_denorm_result); + const uint32_t f_nan_result = uint32_sels(is_nan_msb, f_em_nan, f_inf_result); + const uint32_t f_result = uint32_or(f_s, f_nan_result); + + union { uint32_t ui; float flt; } utof; + utof.ui = f_result; + return utof.flt; + } + + inline uint16_t uint16_min(uint16_t _a, uint16_t _b) + { + return _a > _b ? _b : _a; + } + + inline uint16_t uint16_max(uint16_t _a, uint16_t _b) + { + return _a < _b ? _b : _a; + } + + inline int64_t int64_min(int64_t _a, int64_t _b) + { + return _a < _b ? _a : _b; + } + + inline int64_t int64_max(int64_t _a, int64_t _b) + { + return _a > _b ? _a : _b; + } + + inline int64_t int64_clamp(int64_t _a, int64_t _min, int64_t _max) + { + const int64_t min = int64_min(_a, _max); + const int64_t result = int64_max(_min, min); + + return result; + } + + inline uint64_t uint64_cntbits_ref(uint64_t _val) + { + const uint32_t lo = uint32_t(_val&UINT32_MAX); + const uint32_t hi = uint32_t(_val>>32); + + const uint32_t total = bx::uint32_cntbits(lo) + + bx::uint32_cntbits(hi); + + return total; + } + + /// Count number of bits set. + inline uint64_t uint64_cntbits(uint64_t _val) + { +#if BX_COMPILER_GCC || BX_COMPILER_CLANG + return __builtin_popcountll(_val); +#elif BX_COMPILER_MSVC && BX_ARCH_64BIT + return __popcnt64(_val); +#else + return uint64_cntbits_ref(_val); +#endif // BX_COMPILER_ + } + + inline uint64_t uint64_cntlz_ref(uint64_t _val) + { + return _val & UINT64_C(0xffffffff00000000) + ? uint32_cntlz(uint32_t(_val>>32) ) + : uint32_cntlz(uint32_t(_val) ) + 32 + ; + } + + /// Count number of leading zeros. + inline uint64_t uint64_cntlz(uint64_t _val) + { +#if BX_COMPILER_GCC || BX_COMPILER_CLANG + return __builtin_clzll(_val); +#elif BX_COMPILER_MSVC && BX_PLATFORM_WINDOWS && BX_ARCH_64BIT + unsigned long index; + _BitScanReverse64(&index, _val); + return 63 - index; +#else + return uint64_cntlz_ref(_val); +#endif // BX_COMPILER_ + } + + inline uint64_t uint64_cnttz_ref(uint64_t _val) + { + return _val & UINT64_C(0xffffffff) + ? uint32_cnttz(uint32_t(_val) ) + : uint32_cnttz(uint32_t(_val>>32) ) + 32 + ; + } + + inline uint64_t uint64_cnttz(uint64_t _val) + { +#if BX_COMPILER_GCC || BX_COMPILER_CLANG + return __builtin_ctzll(_val); +#elif BX_COMPILER_MSVC && BX_PLATFORM_WINDOWS && BX_ARCH_64BIT + unsigned long index; + _BitScanForward64(&index, _val); + return index; +#else + return uint64_cnttz_ref(_val); +#endif // BX_COMPILER_ + } + + /// Greatest common divisor. + inline uint32_t uint32_gcd(uint32_t _a, uint32_t _b) + { + do + { + uint32_t tmp = _a % _b; + _a = _b; + _b = tmp; + } + while (_b); + + return _a; + } + + /// Least common multiple. + inline uint32_t uint32_lcm(uint32_t _a, uint32_t _b) + { + return _a * (_b / uint32_gcd(_a, _b) ); + } + + /// Align to arbitrary stride. + inline uint32_t strideAlign(uint32_t _offset, uint32_t _stride) + { + const uint32_t mod = uint32_mod(_offset, _stride); + const uint32_t add = uint32_sub(_stride, mod); + const uint32_t mask = uint32_cmpeq(mod, 0); + const uint32_t tmp = uint32_selb(mask, 0, add); + const uint32_t result = uint32_add(_offset, tmp); + + return result; + } + + /// Align to arbitrary stride and 16-bytes. + inline uint32_t strideAlign16(uint32_t _offset, uint32_t _stride) + { + const uint32_t align = uint32_lcm(16, _stride); + const uint32_t mod = uint32_mod(_offset, align); + const uint32_t mask = uint32_cmpeq(mod, 0); + const uint32_t tmp0 = uint32_selb(mask, 0, align); + const uint32_t tmp1 = uint32_add(_offset, tmp0); + const uint32_t result = uint32_sub(tmp1, mod); + + return result; + } + + /// Align to arbitrary stride and 256-bytes. + inline uint32_t strideAlign256(uint32_t _offset, uint32_t _stride) + { + const uint32_t align = uint32_lcm(256, _stride); + const uint32_t mod = uint32_mod(_offset, align); + const uint32_t mask = uint32_cmpeq(mod, 0); + const uint32_t tmp0 = uint32_selb(mask, 0, align); + const uint32_t tmp1 = uint32_add(_offset, tmp0); + const uint32_t result = uint32_sub(tmp1, mod); + + return result; + } + +} // namespace bx + +#endif // BX_UINT32_T_H_HEADER_GUARD diff --git a/deps/lib/linux-gcc/x64/libbgfx.a b/deps/lib/linux-gcc/x64/libbgfx.a index b518b49..ecf29a9 100644 Binary files a/deps/lib/linux-gcc/x64/libbgfx.a and b/deps/lib/linux-gcc/x64/libbgfx.a differ diff --git a/include/Core/BGFXRenderer.h b/include/Core/BGFXRenderer.h new file mode 100644 index 0000000..4ed22a6 --- /dev/null +++ b/include/Core/BGFXRenderer.h @@ -0,0 +1,94 @@ +#ifndef BGFXRenderer_h__ +#define BGFXRenderer_h__ + +#include +#include + +#include "Util/Rectangle.h" +#include "Core/Camera.h" +#include "Core/RenderQueue.h" + +namespace dd +{ + +class BGFXRenderer +{ +public: + GLFWwindow* Window() const { return m_Window; } + Rectangle Resolution() const { return m_Resolution; } + void SetResolution(const Rectangle& resolution) { m_Resolution = resolution; } + bool Fullscreen() { return m_Fullscreen; } + void SetFullscreen(bool fullscreen) { m_Fullscreen = fullscreen; } + bool VSYNC() const { return m_VSYNC; } + void SetVSYNC(bool vsync) { m_VSYNC = vsync; } + //void SetViewport(const Rectangle& viewport) { m_Viewport = viewport; } + //void SetScissor(const Rectangle& scissor) { m_Scissor = scissor; } + const dd::Camera* Camera() const { return m_Camera; } + void SetCamera(const dd::Camera* camera) + { + if (camera == nullptr) { + m_Camera = m_DefaultCamera.get(); + } else { + m_Camera = camera; + } + } + + void Initialize() + { + // Initialize GLFW + if (!glfwInit()) { + LOG_ERROR("GLFW: Initialization failed"); + exit(EXIT_FAILURE); + } + + // Create a window + GLFWmonitor* monitor = nullptr; + if (m_Fullscreen) { + monitor = glfwGetPrimaryMonitor(); + } + glfwWindowHint(GLFW_SAMPLES, 8); + m_Window = glfwCreateWindow(m_Resolution.Width, m_Resolution.Height, "daydream", monitor, nullptr); + if (!m_Window) { + LOG_ERROR("GLFW: Failed to create window"); + exit(EXIT_FAILURE); + } + //glfwMakeContextCurrent(m_Window); + + // Initialize GLEW +// if (glewInit() != GLEW_OK) { +// LOG_ERROR("GLEW: Initialization failed"); +// exit(EXIT_FAILURE); +// } + //LOG_ERROR("STUFF"); + + // Initialize bgfx + bgfx::glfwSetWindow(m_Window); + bgfx::init(); + bgfx::reset(m_Resolution.Width, m_Resolution.Height, BGFX_RESET_NONE); + bgfx::setDebug(BGFX_DEBUG_TEXT); + bgfx::setViewClear(0, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, 0x303030ff, 1.0f, 0); + } + + void Draw(RenderQueueCollection& rq) + { + bgfx::touch(0); + + bgfx::dbgTextClear(); + bgfx::dbgTextPrintf(0, 1, 0x4f, "daydream"); + + bgfx::frame(); + } + +private: + Rectangle m_Resolution = Rectangle(1280, 720); + bool m_Fullscreen = false; + bool m_VSYNC = false; + std::unique_ptr m_DefaultCamera = nullptr; + const dd::Camera* m_Camera = nullptr; + + GLFWwindow* m_Window = nullptr; +}; + +} + +#endif diff --git a/include/Core/Engine.h b/include/Core/Engine.h index 5e958cd..8b16650 100644 --- a/include/Core/Engine.h +++ b/include/Core/Engine.h @@ -25,7 +25,7 @@ #include "Texture.h" #include "EventBroker.h" #include "RenderQueue.h" -#include "Renderer.h" +#include "BGFXRenderer.h" #include "InputManager.h" //TODO: Remove includes that are only here for the temporary draw solution. #include "World.h" @@ -42,30 +42,30 @@ class Engine public: Engine(int argc, char* argv[]) { - m_EventBroker = std::make_shared(); +// m_EventBroker = std::make_shared(); - m_Renderer = std::make_shared(); + m_Renderer = std::make_shared(); m_Renderer->SetFullscreen(false); - m_Renderer->SetResolution(Rectangle(0, 0, 1920, 1080)); + m_Renderer->SetResolution(Rectangle(0, 0, 1280, 720)); m_Renderer->Initialize(); - m_InputManager = std::make_shared(m_Renderer->Window(), m_EventBroker); +// m_InputManager = std::make_shared(m_Renderer->Window(), m_EventBroker); +// +// m_World = std::make_shared(m_EventBroker); +// +// //TODO: Move this out of engine.h +// m_World->ComponentFactory.Register(); +// m_World->SystemFactory.Register([this]() { return new Systems::TransformSystem(m_World.get(), m_EventBroker); }); +// m_World->AddSystem(); +// m_World->ComponentFactory.Register(); +// m_World->ComponentFactory.Register(); +// m_World->Initialize(); - m_World = std::make_shared(m_EventBroker); - - //TODO: Move this out of engine.h - m_World->ComponentFactory.Register(); - m_World->SystemFactory.Register([this]() { return new Systems::TransformSystem(m_World.get(), m_EventBroker); }); - m_World->AddSystem(); - m_World->ComponentFactory.Register(); - m_World->ComponentFactory.Register(); - m_World->Initialize(); - - auto ent = m_World->CreateEntity(); - std::shared_ptr transform = m_World->AddComponent(ent); - transform->Position = glm::vec3(0.f, 0.f, -10.f); - std::shared_ptr model = m_World->AddComponent(ent); - model->ModelFile = "Models/Core/UnitSphere.obj"; +// auto ent = m_World->CreateEntity(); +// std::shared_ptr transform = m_World->AddComponent(ent); +// transform->Position = glm::vec3(0.f, 0.f, -10.f); +// std::shared_ptr model = m_World->AddComponent(ent); +// model->ModelFile = "Models/Core/UnitSphere.obj"; m_LastTime = glfwGetTime(); @@ -79,26 +79,26 @@ public: double dt = currentTime - m_LastTime; m_LastTime = currentTime; - ResourceManager::Update(); - - // Update input - m_InputManager->Update(dt); - - m_World->Update(dt); - - if (glfwGetKey(m_Renderer->Window(), GLFW_KEY_R)) { - ResourceManager::Reload("Shaders/Deferred/3/Fragment.glsl"); - } - - //TODO Fill up the renderQueue with models (Temp fix) - TEMPAddToRenderQueue(); - - // Render scene - //TODO send renderqueue to draw. +// ResourceManager::Update(); +// +// // Update input +// m_InputManager->Update(dt); +// +// m_World->Update(dt); +// +// if (glfwGetKey(m_Renderer->Window(), GLFW_KEY_R)) { +// ResourceManager::Reload("Shaders/Deferred/3/Fragment.glsl"); +// } +// +// //TODO Fill up the renderQueue with models (Temp fix) +// TEMPAddToRenderQueue(); +// +// // Render scene +// //TODO send renderqueue to draw. m_Renderer->Draw(m_RendererQueue); // Swap event queues - m_EventBroker->Clear(); +// m_EventBroker->Clear(); glfwPollEvents(); } @@ -170,7 +170,7 @@ public: private: //std::shared_ptr m_ResourceManager; std::shared_ptr m_EventBroker; - std::shared_ptr m_Renderer; + std::shared_ptr m_Renderer; RenderQueueCollection m_RendererQueue; std::shared_ptr m_InputManager; std::shared_ptr m_World; diff --git a/include/Core/Util/FileWatcher.h b/include/Core/Util/FileWatcher.h index 6fedf98..311f04e 100755 --- a/include/Core/Util/FileWatcher.h +++ b/include/Core/Util/FileWatcher.h @@ -47,12 +47,13 @@ namespace dd enum class FileWatcher::FileEventFlags { - None = 0, + Nothing = 0, Created = 1 << 0, SizeChanged = 1 << 1, TimestampChanged = 1 << 2, - Deleted = 1 << 3, + Deleted = 1 << 3 }; + inline FileWatcher::FileEventFlags operator|(FileWatcher::FileEventFlags a, FileWatcher::FileEventFlags b) { return static_cast(static_cast(a) | static_cast(b)); } inline bool operator&(FileWatcher::FileEventFlags a, FileWatcher::FileEventFlags b) { return static_cast(a)& static_cast(b); } diff --git a/src/game/CMakeLists.txt b/src/game/CMakeLists.txt index c8c1d17..407bac1 100644 --- a/src/game/CMakeLists.txt +++ b/src/game/CMakeLists.txt @@ -7,6 +7,7 @@ find_package(Boost REQUIRED COMPONENTS system filesystem thread chrono) find_package(assimp REQUIRED) find_package(ZLIB REQUIRED) find_package(PNG REQUIRED) +find_package(X11 REQUIRED) find_package(BGFX REQUIRED) # GLM @@ -19,6 +20,7 @@ include_directories( ${Boost_INCLUDE_DIRS} ${assimp_INCLUDE_DIRS} ${PNG_INCLUDE_DIRS} + ${X11_INCLUDE_DIR} ${BGFX_INCLUDE_DIRS} ) @@ -70,6 +72,7 @@ target_link_libraries(game ${Boost_LIBRARIES} ${assimp_LIBRARIES} ${PNG_LIBRARIES} + ${X11_LIBRARIES} ${BGFX_LIBRARIES} ) @@ -84,6 +87,7 @@ target_link_libraries(breakout ${Boost_LIBRARIES} ${assimp_LIBRARIES} ${PNG_LIBRARIES} + ${X11_LIBRARIES} ${BGFX_LIBRARIES} ) diff --git a/src/game/Core/BGFXRenderer.cpp b/src/game/Core/BGFXRenderer.cpp new file mode 100644 index 0000000..411ec42 --- /dev/null +++ b/src/game/Core/BGFXRenderer.cpp @@ -0,0 +1,3 @@ +#include "PrecompiledHeader.h" +#include "Core/BGFXRenderer.h" + diff --git a/src/game/Core/Util/FileWatcher.cpp b/src/game/Core/Util/FileWatcher.cpp index 1816af8..e71d21c 100755 --- a/src/game/Core/Util/FileWatcher.cpp +++ b/src/game/Core/Util/FileWatcher.cpp @@ -75,7 +75,7 @@ void dd::FileWatcher::Worker::Check() boost::filesystem::path path = kv.first; FileEventCallback_t& callback = kv.second; FileEventFlags flags = UpdateFileInfo(path); - if (flags != FileEventFlags::None && callback != nullptr) + if (flags != FileEventFlags::Nothing && callback != nullptr) { callback(path.string(), flags); } @@ -93,7 +93,7 @@ dd::FileWatcher::Worker::FileInfo dd::FileWatcher::Worker::GetFileInfo(boost::fi dd::FileWatcher::FileEventFlags dd::FileWatcher::Worker::UpdateFileInfo(boost::filesystem::path path) { - FileEventFlags flags = FileEventFlags::None; + FileEventFlags flags = FileEventFlags::Nothing; if (boost::filesystem::exists(path)) { FileInfo fi = GetFileInfo(path);