Semi-working base for bgfx renderer

This commit is contained in:
2015-09-08 16:13:59 +02:00
parent c7f17c8ef0
commit c24b039005
47 changed files with 11176 additions and 43 deletions
+6 -1
View File
@@ -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)
+208
View File
@@ -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 <memory.h>
#include <string.h> //::memmove
#include <new>
#if BX_CONFIG_ALLOCATOR_CRT
# include <malloc.h>
#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 <typename ObjectT>
inline void deleteObject(AllocatorI* _allocator, ObjectT* _object, size_t _align = 0, const char* _file = NULL, uint32_t _line = 0)
{
if (NULL != _object)
{
_object->~ObjectT();
free(_allocator, _object, _align, _file, _line);
}
}
#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
+99
View File
@@ -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
+60
View File
@@ -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 <stdint.h> // uint32_t
#include <stdlib.h> // size_t
#include "config.h"
#include "macros.h"
namespace bx
{
// http://cnicholson.net/2011/01/stupid-c-tricks-a-better-sizeof_array/
template<typename T, size_t N> 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<bool>
inline bool isEnabled()
{
return true;
}
template<>
inline bool isEnabled<false>()
{
return false;
}
#define BX_ENABLED(_x) bx::isEnabled<!!(_x)>()
inline bool ignoreC4127(bool _x)
{
return _x;
}
#define BX_IGNORE_C4127(_x) bx::ignoreC4127(!!(_x) )
template<typename Ty>
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
+925
View File
@@ -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 <bx/cl.h> into .cpp file.
///
/// To use it, just #include <bx/cl.h> 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 <OpenCL/cl_platform.h>
#else
#include <CL/cl_platform.h>
#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
+188
View File
@@ -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
+46
View File
@@ -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
+152
View File
@@ -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 <ppcintrinsics.h>
# include <xtl.h>
# else
# include <math.h> // math.h is included because VS bitches:
// warning C4985: 'ceil': attributes not present on previous declaration.
// must be included before intrin.h.
# include <intrin.h>
# include <windows.h>
# 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
+73
View File
@@ -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 <android/log.h>
#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 <Foundation/NSObjCRuntime.h>
# else
# include <CoreFoundation/CFString.h>
extern "C" void NSLog(CFStringRef _format, ...);
# endif // defined(__OBJC__)
#elif 0 // BX_PLATFORM_EMSCRIPTEN
# include <emscripten.h>
#else
# include <stdio.h>
#endif // BX_PLATFORM_WINDOWS
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
+87
View File
@@ -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 <typename Ty>
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 <typename Ty>
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 <typename Ty>
inline Ty toHostEndian(const Ty _in, bool _fromLittleEndian)
{
#if BX_CPU_ENDIAN_LITTLE
return _fromLittleEndian ? _in : endianSwap(_in);
#else
return _fromLittleEndian ? endianSwap(_in) : _in;
#endif // BX_CPU_ENDIAN_LITTLE
}
} // namespace bx
#endif // BX_ENDIAN_H_HEADER_GUARD
+482
View File
@@ -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 <math.h>
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<const uint32_t*>(_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<uint32_t*>(_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<uint32_t*>(_ptr);
result[0] = _a.uxyzw[0];
}
BX_FLOAT4_FORCE_INLINE void float4_stream(void* _ptr, float4_t _a)
{
uint32_t* result = reinterpret_cast<uint32_t*>(_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<const uint32_t*>(_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
+525
View File
@@ -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
+495
View File
@@ -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
+604
View File
@@ -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 <math.h> // 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<const uint32_t*>(_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<uint32_t*>(_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<uint32_t*>(_ptr);
result[0] = _a.uxyzw[0];
}
BX_FLOAT4_FORCE_INLINE void float4_stream(void* _ptr, float4_t _a)
{
uint32_t* result = reinterpret_cast<uint32_t*>(_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<const uint32_t*>(_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
+461
View File
@@ -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 <emmintrin.h> // __m128i
#if defined(__SSE4_1__)
# include <smmintrin.h>
#endif // defined(__SSE4_1__)
#include <xmmintrin.h> // __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<const float*>(_ptr) );
}
BX_FLOAT4_FORCE_INLINE void float4_st(void* _ptr, float4_t _a)
{
_mm_store_ps(reinterpret_cast<float*>(_ptr), _a);
}
BX_FLOAT4_FORCE_INLINE void float4_stx(void* _ptr, float4_t _a)
{
_mm_store_ss(reinterpret_cast<float*>(_ptr), _a);
}
BX_FLOAT4_FORCE_INLINE void float4_stream(void* _ptr, float4_t _a)
{
_mm_stream_ps(reinterpret_cast<float*>(_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<const float*>(_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
+266
View File
@@ -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)
+35
View File
@@ -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
+158
View File
@@ -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
+71
View File
@@ -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 <typename Ty>
class Container : public ContainerBase
{
public:
inline Container(const Ty& _container)
: m_container(_container)
, m_break(0)
, m_it( _container.begin() )
, m_itEnd( _container.end() )
{
}
inline bool condition() const
{
return (!m_break++ && m_it != m_itEnd);
}
const Ty& m_container;
mutable int m_break;
mutable typename Ty::const_iterator m_it;
mutable typename Ty::const_iterator m_itEnd;
};
template <typename Ty>
inline Ty* pointer(const Ty&)
{
return 0;
}
template <typename Ty>
inline Container<Ty> containerNew(const Ty& _container)
{
return Container<Ty>(_container);
}
template <typename Ty>
inline const Container<Ty>* container(const ContainerBase* _base, const Ty*)
{
return static_cast<const Container<Ty>*>(_base);
}
} // namespace foreach_ns
#define foreach(_variable, _container) \
for (const bx::foreach_ns::ContainerBase &__temp_container__ = bx::foreach_ns::containerNew(_container); \
bx::foreach_ns::container(&__temp_container__, true ? 0 : bx::foreach_ns::pointer(_container) )->condition(); \
++bx::foreach_ns::container(&__temp_container__, true ? 0 : bx::foreach_ns::pointer(_container) )->m_it) \
for (_variable = *container(&__temp_container__, true ? 0 : bx::foreach_ns::pointer(_container) )->m_it; \
bx::foreach_ns::container(&__temp_container__, true ? 0 : bx::foreach_ns::pointer(_container) )->m_break; \
--bx::foreach_ns::container(&__temp_container__, true ? 0 : bx::foreach_ns::pointer(_container) )->m_break)
} // namespace bx
#endif // BX_FOREACH_H_HEADER_GUARD
+976
View File
@@ -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 <math.h>
#include <string.h>
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
+427
View File
@@ -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<const uint8_t*>(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 <uint16_t MaxHandlesT>
class HandleAllocT : public HandleAlloc
{
public:
HandleAllocT()
: HandleAlloc(MaxHandlesT)
{
}
~HandleAllocT()
{
}
private:
uint16_t m_padding[2*MaxHandlesT];
};
template <uint16_t MaxHandlesT>
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 <uint16_t MaxHandlesT>
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<MaxHandlesT> m_list;
HandleAllocT<MaxHandlesT> m_alloc;
};
} // namespace bx
#endif // BX_HANDLE_ALLOC_H_HEADER_GUARD
+170
View File
@@ -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<typename Ty>
void add(Ty _value)
{
add(&_value, sizeof(Ty) );
}
uint32_t end()
{
mmix(m_hash, m_tail);
mmix(m_hash, m_size);
m_hash ^= m_hash >> 13;
m_hash *= MURMUR_M;
m_hash ^= m_hash >> 15;
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 <typename Ty>
inline uint32_t hashMurmur2A(const Ty& _data)
{
return hashMurmur2A(&_data, sizeof(Ty) );
}
} // namespace bx
#endif // BX_HASH_H_HEADER_GUARD
+226
View File
@@ -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
+29
View File
@@ -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>
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
+54
View File
@@ -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 <typename Ty>
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<Ty> m_queue;
};
} // namespace bx
#endif // BX_MPSCQUEUE_H_HEADER_GUARD
+148
View File
@@ -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 <pthread.h>
#elif BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 || BX_PLATFORM_WINRT
# include <errno.h>
#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
+209
View File
@@ -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 <windows.h>
#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.h> // sched_yield
# if BX_PLATFORM_FREEBSD \
|| BX_PLATFORM_IOS \
|| BX_PLATFORM_NACL \
|| BX_PLATFORM_OSX \
|| BX_PLATFORM_PS4
# include <pthread.h> // mach_port_t
# endif // BX_PLATFORM_IOS || BX_PLATFORM_OSX || BX_PLATFORM_NACL
# if BX_PLATFORM_NACL
# include <sys/nacl_syscalls.h> // nanosleep
# else
# include <time.h> // nanosleep
# if !BX_PLATFORM_PS4
# include <dlfcn.h> // dlopen, dlclose, dlsym
# endif // !BX_PLATFORM_PS4
# endif // BX_PLATFORM_NACL
# if BX_PLATFORM_LINUX || BX_PLATFORM_RPI
# include <unistd.h> // syscall
# include <sys/syscall.h>
# 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 <direct.h> // _getcwd
#else
# include <unistd.h> // 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
+310
View File
@@ -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 <winapifamily.h>
# 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 <ppapi/c/pp_macros.h>
# undef BX_PLATFORM_NACL
# define BX_PLATFORM_NACL PPAPI_RELEASE
#elif defined(__ANDROID__)
// Android compiler defines __linux__
# include <android/api-level.h>
# 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
+80
View File
@@ -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 <unistd.h>
#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<char *const*>(&_argv[1]) );
BX_UNUSED(result);
return NULL;
}
return (void*)uintptr_t(pid);
#elif BX_PLATFORM_WINDOWS
STARTUPINFO si;
memset(&si, 0, sizeof(STARTUPINFO) );
si.cb = sizeof(STARTUPINFO);
PROCESS_INFORMATION pi;
memset(&pi, 0, sizeof(PROCESS_INFORMATION) );
int32_t total = 0;
for (uint32_t ii = 0; NULL != _argv[ii]; ++ii)
{
total += (int32_t)strlen(_argv[ii]) + 1;
}
char* temp = (char*)alloca(total);
int32_t len = 0;
for(uint32_t ii = 0; NULL != _argv[ii]; ++ii)
{
len += snprintf(&temp[len], bx::uint32_imax(0, total-len)
, "%s "
, _argv[ii]
);
}
bool ok = CreateProcessA(_argv[0]
, temp
, NULL
, NULL
, false
, 0
, NULL
, NULL
, &si
, &pi
);
if (ok)
{
return pi.hProcess;
}
return NULL;
#else
return NULL;
#endif // BX_PLATFORM_LINUX
}
} // namespace bx
#endif // BX_PROCESS_H_HEADER_GUARD
+169
View File
@@ -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<<BX_RADIXSORT_BITS)
#define BX_RADIXSORT_BIT_MASK (BX_RADIXSORT_HISTOGRAM_SIZE-1)
template <typename Ty>
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 <typename Ty>
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
+589
View File
@@ -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 <stdarg.h> // va_list
#include <stdio.h>
#include <string.h>
#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<typename Ty>
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<typename Ty>
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<typename Ty>
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<typename Ty>
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<typename Ty>
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
+342
View File
@@ -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 <typename Control>
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 <typename Ty>
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<RingBufferControl> ReadRingBuffer;
typedef ReadRingBufferT<SpScRingBufferControl> SpScReadRingBuffer;
template <typename Control>
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<Control>& _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<RingBufferControl> WriteRingBuffer;
typedef WriteRingBufferT<SpScRingBufferControl> SpScWriteRingBuffer;
} // namespace bx
#endif // BX_RINGBUFFER_H_HEADER_GUARD
+182
View File
@@ -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 <typename Ty>
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 <typename Ty>
inline float frndh(Ty* _rng)
{
return 2.0f * bx::frnd(_rng) - 1.0f;
}
/// Generate random point on unit sphere.
template <typename Ty>
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 <typename Ty>
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
+243
View File
@@ -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 <errno.h>
# include <semaphore.h>
# include <time.h>
# include <pthread.h>
#elif BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 || BX_PLATFORM_WINRT
# include <windows.h>
# include <limits.h>
#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
+206
View File
@@ -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 <list>
namespace bx
{
// http://drdobbs.com/article/print?articleId=210604448&siteSectionName=
template <typename Ty>
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<typename Ty>
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<Ty*> 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 <typename Ty>
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<void> m_queue;
};
#endif // BX_CONFIG_SUPPORTS_THREADING
} // namespace bx
#endif // BX_SPSCQUEUE_H_HEADER_GUARD
+506
View File
@@ -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 <alloca.h>
#include <ctype.h> // tolower
#include <stdarg.h> // va_list
#include <stdio.h> // vsnprintf, vsnwprintf
#include <string.h>
#include <wchar.h> // 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 <typename Ty>
inline void stringPrintfVargs(Ty& _out, const char* _format, va_list _argList)
{
char temp[2048];
char* out = temp;
int32_t len = bx::vsnprintf(out, sizeof(temp), _format, _argList);
if ( (int32_t)sizeof(temp) < len)
{
out = (char*)alloca(len+1);
len = bx::vsnprintf(out, len, _format, _argList);
}
out[len] = '\0';
_out.append(out);
}
///
template <typename Ty>
inline void stringPrintf(Ty& _out, const char* _format, ...)
{
va_list argList;
va_start(argList, _format);
stringPrintfVargs(_out, _format, argList);
va_end(argList);
}
/// 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 <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/// 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
+262
View File
@@ -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 <pthread.h>
#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
+62
View File
@@ -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 <time.h> // clock, clock_gettime
#elif BX_PLATFORM_EMSCRIPTEN
# include <emscripten.h>
#elif BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT
# include <windows.h>
#else
# include <sys/time.h> // gettimeofday
#endif // BX_PLATFORM_
namespace bx
{
inline int64_t getHPCounter()
{
#if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 || BX_PLATFORM_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
+146
View File
@@ -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 <stdint.h>
#include <stdio.h>
#include <ctype.h>
namespace bx
{
// Reference:
// http://msdn.microsoft.com/en-us/library/a1y7w461.aspx
static inline const char* tokenizeCommandLine(const char* _commandLine, char* _buffer, uint32_t& _bufferSize, int& _argc, char* _argv[], int _maxArgvs, char _term = '\0')
{
int argc = 0;
const char* curr = _commandLine;
char* currOut = _buffer;
char term = ' ';
bool sub = false;
enum ParserState
{
SkipWhitespace,
SetTerm,
Copy,
Escape,
End,
};
ParserState state = SkipWhitespace;
while ('\0' != *curr
&& _term != *curr
&& argc < _maxArgvs)
{
switch (state)
{
case SkipWhitespace:
for (; isspace(*curr); ++curr) {}; // skip whitespace
state = SetTerm;
break;
case SetTerm:
if ('"' == *curr)
{
term = '"';
++curr; // skip begining quote
}
else
{
term = ' ';
}
_argv[argc] = currOut;
++argc;
state = Copy;
break;
case Copy:
if ('\\' == *curr)
{
state = Escape;
}
else if ('"' == *curr
&& '"' != term)
{
sub = !sub;
}
else if (isspace(*curr) && !sub)
{
state = End;
}
else if (term != *curr || sub)
{
*currOut = *curr;
++currOut;
}
else
{
state = End;
}
++curr;
break;
case Escape:
{
const char* start = --curr;
for (; '\\' == *curr; ++curr) {};
if ('"' != *curr)
{
int count = (int)(curr-start);
curr = start;
for (int ii = 0; ii < count; ++ii)
{
*currOut = *curr;
++currOut;
++curr;
}
}
else
{
curr = start+1;
*currOut = *curr;
++currOut;
++curr;
}
}
state = Copy;
break;
case End:
*currOut = '\0';
++currOut;
state = SkipWhitespace;
break;
}
}
*currOut = '\0';
if (0 < argc
&& '\0' == _argv[argc-1][0])
{
--argc;
}
_bufferSize = (uint32_t)(currOut - _buffer);
_argc = argc;
if ('\0' != *curr)
{
++curr;
}
return curr;
}
} // namespace bx
#endif // TOKENIZE_CMD_H_HEADER_GUARD
+755
View File
@@ -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 <macton@gmail.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE
#ifndef BX_UINT32_T_H_HEADER_GUARD
#define BX_UINT32_T_H_HEADER_GUARD
#include "bx.h"
#if BX_COMPILER_MSVC
# if BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT
# include <math.h> // math.h is included because VS bitches:
// warning C4985: 'ceil': attributes not present on previous declaration.
// must be included before intrin.h.
# include <intrin.h>
# pragma intrinsic(_BitScanForward)
# pragma intrinsic(_BitScanReverse)
# 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
Binary file not shown.
+94
View File
@@ -0,0 +1,94 @@
#ifndef BGFXRenderer_h__
#define BGFXRenderer_h__
#include <bgfx.h>
#include <bgfxplatform.h>
#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<dd::Camera> m_DefaultCamera = nullptr;
const dd::Camera* m_Camera = nullptr;
GLFWwindow* m_Window = nullptr;
};
}
#endif
+38 -38
View File
@@ -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<EventBroker>();
// m_EventBroker = std::make_shared<EventBroker>();
m_Renderer = std::make_shared<Renderer>();
m_Renderer = std::make_shared<BGFXRenderer>();
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<InputManager>(m_Renderer->Window(), m_EventBroker);
// m_InputManager = std::make_shared<InputManager>(m_Renderer->Window(), m_EventBroker);
//
// m_World = std::make_shared<World>(m_EventBroker);
//
// //TODO: Move this out of engine.h
// m_World->ComponentFactory.Register<Components::Transform>();
// m_World->SystemFactory.Register<Systems::TransformSystem>([this]() { return new Systems::TransformSystem(m_World.get(), m_EventBroker); });
// m_World->AddSystem<Systems::TransformSystem>();
// m_World->ComponentFactory.Register<Components::Model>();
// m_World->ComponentFactory.Register<Components::Template>();
// m_World->Initialize();
m_World = std::make_shared<World>(m_EventBroker);
//TODO: Move this out of engine.h
m_World->ComponentFactory.Register<Components::Transform>();
m_World->SystemFactory.Register<Systems::TransformSystem>([this]() { return new Systems::TransformSystem(m_World.get(), m_EventBroker); });
m_World->AddSystem<Systems::TransformSystem>();
m_World->ComponentFactory.Register<Components::Model>();
m_World->ComponentFactory.Register<Components::Template>();
m_World->Initialize();
auto ent = m_World->CreateEntity();
std::shared_ptr<Components::Transform> transform = m_World->AddComponent<Components::Transform>(ent);
transform->Position = glm::vec3(0.f, 0.f, -10.f);
std::shared_ptr<Components::Model> model = m_World->AddComponent<Components::Model>(ent);
model->ModelFile = "Models/Core/UnitSphere.obj";
// auto ent = m_World->CreateEntity();
// std::shared_ptr<Components::Transform> transform = m_World->AddComponent<Components::Transform>(ent);
// transform->Position = glm::vec3(0.f, 0.f, -10.f);
// std::shared_ptr<Components::Model> model = m_World->AddComponent<Components::Model>(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<ResourceManager> m_ResourceManager;
std::shared_ptr<EventBroker> m_EventBroker;
std::shared_ptr<Renderer> m_Renderer;
std::shared_ptr<BGFXRenderer> m_Renderer;
RenderQueueCollection m_RendererQueue;
std::shared_ptr<InputManager> m_InputManager;
std::shared_ptr<World> m_World;
+3 -2
View File
@@ -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<FileWatcher::FileEventFlags>(static_cast<int>(a) | static_cast<int>(b)); }
inline bool operator&(FileWatcher::FileEventFlags a, FileWatcher::FileEventFlags b) { return static_cast<int>(a)& static_cast<int>(b); }
+4
View File
@@ -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}
)
+3
View File
@@ -0,0 +1,3 @@
#include "PrecompiledHeader.h"
#include "Core/BGFXRenderer.h"
+2 -2
View File
@@ -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);