Compare commits

..

49 Commits

Author SHA1 Message Date
Recep Aslantas
65fd77d255 Merge branch 'master' into fix-simd-signmask 2023-04-22 23:53:20 +03:00
Recep Aslantas
5883ed3495 Merge pull request #292 from myfreeer/fix-simd-signmask-wasm
wasm: replace usage of -0.f to 0x80000000
2023-04-22 10:11:46 +03:00
Recep Aslantas
e2e923554b Merge pull request #291 from recp/fix-simd-signmask
simd, sse: use 0x80000000 insteaf of -0.f to fix fastmath on msvc
2023-04-22 10:11:17 +03:00
myfreeer
6b2c91ecf7 wasm: replace usage of -0.f to 0x80000000
Part of https://github.com/recp/cglm/pull/291
2023-04-22 10:50:54 +08:00
Recep Aslantas
a4b8778be9 fixes for "simd, sse: use 0x80000000 insteaf of -0.f to fix fastmath on msvc" 2023-04-21 22:42:04 +03:00
Recep Aslantas
5ce7dff812 Merge remote-tracking branch 'origin/master' into fix-simd-signmask 2023-04-21 22:31:55 +03:00
Recep Aslantas
13036036c4 fix existing tests build 2023-04-21 22:29:55 +03:00
Recep Aslantas
c1ff76d3b1 fix existing tests build 2023-04-21 22:15:04 +03:00
Recep Aslantas
17b3911e7c fix struct api calls 2023-04-21 21:20:11 +03:00
Recep Aslantas
7307b1cbbe simd, sse: use 0x80000000 insteaf of -0.f to fix fastmath on msvc 2023-04-21 20:36:50 +03:00
Recep Aslantas
391d8670c2 simd, sse: use 0x80000000 insteaf of -0.f to fix fastmath on msvc 2023-04-21 20:14:58 +03:00
Recep Aslantas
8d441902c0 fix struct api calls 2023-04-21 20:07:14 +03:00
Recep Aslantas
490d0bb9a1 Merge pull request #290 from recp/structapi-conf
struct: provide option to omit struct api namespace e.g. `glms_` and …
2023-04-21 17:38:22 +03:00
Recep Aslantas
4c6fb156ef Merge pull request #286 from myfreeer/master
WIP: Wasm simd128 support
2023-04-21 16:49:51 +03:00
myfreeer
81b7c90271 simd128: simplify calls 2023-04-15 22:06:04 +08:00
myfreeer
765771227a io: add case of wasm simd128 2023-04-08 18:28:49 +08:00
myfreeer
1940f1d4bc wasm: build with emsdk on github actions 2023-04-08 15:21:29 +08:00
myfreeer
061f096d8f wasm: add --no-verbose to wget 2023-04-08 14:12:23 +08:00
myfreeer
884be84506 wasm: fix clang path for github actions 2023-04-08 14:07:00 +08:00
myfreeer
18ed15c53a wasm: init github action ci 2023-04-08 14:05:01 +08:00
myfreeer
2614a1805d Merge remote-tracking branch 'upstream/master' 2023-04-08 13:41:53 +08:00
myfreeer
d7c0edcbd9 simd128: minor lint 2023-04-08 13:40:46 +08:00
myfreeer
07bc4be18b simd128: cmake options
After this, the required options for cmake are listed below:
```
-DCMAKE_C_FLAGS="-msimd128"
-DCMAKE_TOOLCHAIN_FILE=/path/to/wasi-sdk-19.0/share/cmake/wasi-sdk.cmake
-DWASI_SDK_PREFIX=/path/to/wasi-sdk-19.0
-DCGLM_USE_TEST=ON
```
If compiling to wasi with simd128 support, `-DCMAKE_C_FLAGS="-msimd128"` can be removed.
If tests are not needed, `-DCGLM_USE_TEST=ON` can be removed.
2023-04-02 13:09:00 +08:00
myfreeer
3a9e4df393 simd128: handle both sse2 and simd128 enabled by Emscripten
https://github.com/recp/cglm/pull/286#issuecomment-1492985403
2023-04-02 12:39:20 +08:00
myfreeer
7ca9a64ecf simd128: code style 2023-04-01 19:38:57 +08:00
myfreeer
51ce4db82e simd128: code style 2023-04-01 19:38:28 +08:00
myfreeer
73adfe08c0 simd128: inline _mm_cvtss_f32 2023-04-01 19:34:19 +08:00
myfreeer
48d6ab79bd simd128: inline _mm_movehl_ps 2023-04-01 19:28:45 +08:00
myfreeer
e40b477929 simd128: inline _mm_movelh_ps 2023-04-01 19:19:49 +08:00
myfreeer
5e05eec6d6 simd128: inline _MM_TRANSPOSE4_PS 2023-04-01 19:03:48 +08:00
myfreeer
3aca10ecda simd128: minor lint 2023-03-29 20:41:47 +08:00
myfreeer
5c7cd42407 simd128: inline _mm_sqrt_ss 2023-03-29 20:22:03 +08:00
myfreeer
e27f80b0bb simd128: inline _mm_rcp_ps 2023-03-29 20:16:16 +08:00
myfreeer
3845345f4c simd128: inline _mm_storeu_ps and _mm_store_ss 2023-03-29 20:12:51 +08:00
myfreeer
998d9626a2 simd128: inline _mm_unpackhi_ps and _mm_unpacklo_ps 2023-03-26 19:34:08 +08:00
myfreeer
84b482971d simd128: inline _mm_shuffle_ps 2023-03-26 19:34:08 +08:00
myfreeer
f24ec41a26 simd128: inline _mm_shuffle_ps for glmm_shuff1 2023-03-26 19:34:08 +08:00
myfreeer
e62b782039 simd128: fix a const in glm_mat4_inv_fast_wasm
making it the same as glm_mat4_inv_wasm, does not make any difference in tests
2023-03-26 19:34:08 +08:00
myfreeer
be76d96e8f simd128: inline _mm_set_ps 2023-03-26 19:34:07 +08:00
myfreeer
03c7bee863 simd128: inline some functions 2023-03-26 19:34:07 +08:00
myfreeer
71c585b159 simd128: enable in headers 2023-03-26 19:34:07 +08:00
myfreeer
6b7a63953c simd128: enable in mat2 2023-03-26 19:34:07 +08:00
myfreeer
fdef58bd1a simd128: enable in mat3 2023-03-26 19:34:07 +08:00
myfreeer
a0dd85f3d1 simd128: enable in quat 2023-03-26 19:34:07 +08:00
myfreeer
84c521c203 simd128: enable in mat4 2023-03-26 19:34:07 +08:00
myfreeer
5d60c17435 simd128: fix tests for vec4_norm_one and vec4_norm_inf 2023-03-26 19:34:07 +08:00
myfreeer
da5f18f10f simd128: fix tests for glm_inv_tr 2023-03-26 19:34:07 +08:00
myfreeer
2bc9573e1a simd128: include a fix 2023-03-26 19:34:07 +08:00
myfreeer
576d1d141e initial code on wasm simd128 2023-03-26 19:34:07 +08:00
46 changed files with 1532 additions and 256 deletions

97
.github/workflows/cmake-wasm.yml vendored Normal file
View File

@@ -0,0 +1,97 @@
name: CMake WebAssembly
on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
env:
wasmtime_version: v7.0.0
wasmer_version: v3.1.1
jobs:
build_wasi_sdk:
strategy:
matrix:
BUILD_TYPE: [Release, Debug, RelWithDebInfo, MinSizeRel]
C_FLAGS: ['', '-msimd128']
wasi_sdk_version: [19, 20]
# The CMake configure and build commands are platform agnostic and should work equally well on Windows or Mac.
# You can convert this to a matrix build if you need cross-platform coverage.
# See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Downloading wasi-sdk
run: |
cd ${{github.workspace}}
wget --no-verbose https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-${{matrix.wasi_sdk_version}}/wasi-sdk-${{matrix.wasi_sdk_version}}.0-linux.tar.gz
tar xf wasi-sdk-${{matrix.wasi_sdk_version}}.0-linux.tar.gz
- name: Configure CMake
# Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make.
# See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{matrix.BUILD_TYPE}} -DCMAKE_C_FLAGS="${{matrix.C_FLAGS}}" -DCMAKE_TOOLCHAIN_FILE=${{github.workspace}}/wasi-sdk-${{matrix.wasi_sdk_version}}.0/share/cmake/wasi-sdk.cmake -DWASI_SDK_PREFIX=${{github.workspace}}/wasi-sdk-${{matrix.wasi_sdk_version}}.0 -DCGLM_USE_TEST=ON
- name: Build
# Build your program with the given configuration
run: cmake --build ${{github.workspace}}/build --config ${{matrix.BUILD_TYPE}}
- name: Test with wasmtime
run: |
cd ${{github.workspace}}
ls -lh ${{github.workspace}}/build/
wget --no-verbose https://github.com/bytecodealliance/wasmtime/releases/download/${{env.wasmtime_version}}/wasmtime-${{env.wasmtime_version}}-x86_64-linux.tar.xz
tar xf wasmtime-${{env.wasmtime_version}}-x86_64-linux.tar.xz
./wasmtime-${{env.wasmtime_version}}-x86_64-linux/wasmtime run --wasm-features simd ${{github.workspace}}/build/tests
- name: Test with wasmer
run: |
cd ${{github.workspace}}
mkdir wasmer
cd wasmer
wget --no-verbose https://github.com/wasmerio/wasmer/releases/download/${{env.wasmer_version}}/wasmer-linux-amd64.tar.gz
tar xf wasmer-linux-amd64.tar.gz
./bin/wasmer run --enable-simd ${{github.workspace}}/build/tests
build_emsdk:
strategy:
matrix:
BUILD_TYPE: [Release, Debug, RelWithDebInfo, MinSizeRel]
C_FLAGS: ['', '-msimd128', '-msse -msse2 -msimd128', '-msse -msse2 -msse3 -msse4 -msimd128']
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup emsdk
uses: mymindstorm/setup-emsdk@v11
- name: Verify emsdk
run: emcc -v
- name: Configure CMake
# Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make.
# See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type
run: emcmake cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{matrix.BUILD_TYPE}} -DCMAKE_C_FLAGS="${{matrix.C_FLAGS}}" -DCMAKE_EXE_LINKER_FLAGS="-s STANDALONE_WASM" -DCGLM_STATIC=ON -DCGLM_USE_TEST=ON
- name: Build
# Build your program with the given configuration
run: cmake --build ${{github.workspace}}/build --config ${{matrix.BUILD_TYPE}}
- name: Test with wasmtime
run: |
cd ${{github.workspace}}
ls -lh ${{github.workspace}}/build/
wget --no-verbose https://github.com/bytecodealliance/wasmtime/releases/download/${{env.wasmtime_version}}/wasmtime-${{env.wasmtime_version}}-x86_64-linux.tar.xz
tar xf wasmtime-${{env.wasmtime_version}}-x86_64-linux.tar.xz
./wasmtime-${{env.wasmtime_version}}-x86_64-linux/wasmtime run --wasm-features simd ${{github.workspace}}/build/tests.wasm
- name: Test with wasmer
run: |
cd ${{github.workspace}}
mkdir wasmer
cd wasmer
wget --no-verbose https://github.com/wasmerio/wasmer/releases/download/${{env.wasmer_version}}/wasmer-linux-amd64.tar.gz
tar xf wasmer-linux-amd64.tar.gz
./bin/wasmer run --enable-simd ${{github.workspace}}/build/tests.wasm

View File

@@ -16,6 +16,11 @@ option(CGLM_STATIC "Static build" OFF)
option(CGLM_USE_C99 "" OFF) option(CGLM_USE_C99 "" OFF)
option(CGLM_USE_TEST "Enable Tests" OFF) option(CGLM_USE_TEST "Enable Tests" OFF)
if(CMAKE_SYSTEM_NAME STREQUAL WASI)
set(CGLM_STATIC ON CACHE BOOL "Static option" FORCE)
set(CGLM_SHARED OFF CACHE BOOL "Shared option" FORCE)
endif()
if(NOT CGLM_STATIC AND CGLM_SHARED) if(NOT CGLM_STATIC AND CGLM_SHARED)
set(CGLM_BUILD SHARED) set(CGLM_BUILD SHARED)
else(CGLM_STATIC) else(CGLM_STATIC)

View File

@@ -243,11 +243,6 @@ test_tests_SOURCES=\
test/runner.c \ test/runner.c \
test/src/test_common.c \ test/src/test_common.c \
test/src/tests.c \ test/src/tests.c \
test/src/test_cam.c \
test/src/test_cam_lh_zo.c \
test/src/test_cam_rh_zo.c \
test/src/test_cam_lh_no.c \
test/src/test_cam_rh_no.c \
test/src/test_clamp.c \ test/src/test_clamp.c \
test/src/test_euler.c \ test/src/test_euler.c \
test/src/test_bezier.c \ test/src/test_bezier.c \

View File

@@ -30,6 +30,10 @@
# include "simd/neon/affine.h" # include "simd/neon/affine.h"
#endif #endif
#ifdef CGLM_SIMD_WASM
# include "simd/wasm/affine.h"
#endif
/*! /*!
* @brief this is similar to glm_mat4_mul but specialized to affine transform * @brief this is similar to glm_mat4_mul but specialized to affine transform
* *
@@ -49,7 +53,9 @@
CGLM_INLINE CGLM_INLINE
void void
glm_mul(mat4 m1, mat4 m2, mat4 dest) { glm_mul(mat4 m1, mat4 m2, mat4 dest) {
#ifdef __AVX__ #if defined(__wasm__) && defined(__wasm_simd128__)
glm_mul_wasm(m1, m2, dest);
#elif defined(__AVX__)
glm_mul_avx(m1, m2, dest); glm_mul_avx(m1, m2, dest);
#elif defined( __SSE__ ) || defined( __SSE2__ ) #elif defined( __SSE__ ) || defined( __SSE2__ )
glm_mul_sse2(m1, m2, dest); glm_mul_sse2(m1, m2, dest);
@@ -107,7 +113,9 @@ glm_mul(mat4 m1, mat4 m2, mat4 dest) {
CGLM_INLINE CGLM_INLINE
void void
glm_mul_rot(mat4 m1, mat4 m2, mat4 dest) { glm_mul_rot(mat4 m1, mat4 m2, mat4 dest) {
#if defined( __SSE__ ) || defined( __SSE2__ ) #if defined(__wasm__) && defined(__wasm_simd128__)
glm_mul_rot_wasm(m1, m2, dest);
#elif defined( __SSE__ ) || defined( __SSE2__ )
glm_mul_rot_sse2(m1, m2, dest); glm_mul_rot_sse2(m1, m2, dest);
#elif defined(CGLM_NEON_FP) #elif defined(CGLM_NEON_FP)
glm_mul_rot_neon(m1, m2, dest); glm_mul_rot_neon(m1, m2, dest);
@@ -156,7 +164,9 @@ glm_mul_rot(mat4 m1, mat4 m2, mat4 dest) {
CGLM_INLINE CGLM_INLINE
void void
glm_inv_tr(mat4 mat) { glm_inv_tr(mat4 mat) {
#if defined( __SSE__ ) || defined( __SSE2__ ) #if defined(__wasm__) && defined(__wasm_simd128__)
glm_inv_tr_wasm(mat);
#elif defined( __SSE__ ) || defined( __SSE2__ )
glm_inv_tr_sse2(mat); glm_inv_tr_sse2(mat);
#elif defined(CGLM_NEON_FP) #elif defined(CGLM_NEON_FP)
glm_inv_tr_neon(mat); glm_inv_tr_neon(mat);

View File

@@ -68,7 +68,10 @@
CGLM_INLINE CGLM_INLINE
void void
glm_arch_print_name(FILE* __restrict ostream) { glm_arch_print_name(FILE* __restrict ostream) {
#ifdef CGLM_SIMD_x86 #if defined(CGLM_SIMD_WASM)
fprintf(ostream, CGLM_PRINT_COLOR "\ncglm arch: wasm SIMD128"
"\n\n" CGLM_PRINT_COLOR_RESET);
#elif defined(CGLM_SIMD_x86)
fprintf(ostream, CGLM_PRINT_COLOR "\ncglm arch: x86 SSE*" fprintf(ostream, CGLM_PRINT_COLOR "\ncglm arch: x86 SSE*"
#ifdef __AVX__ #ifdef __AVX__
" AVX" " AVX"

View File

@@ -44,6 +44,10 @@
# include "simd/neon/mat2.h" # include "simd/neon/mat2.h"
#endif #endif
#ifdef CGLM_SIMD_WASM
# include "simd/wasm/mat2.h"
#endif
#define GLM_MAT2_IDENTITY_INIT {{1.0f, 0.0f}, {0.0f, 1.0f}} #define GLM_MAT2_IDENTITY_INIT {{1.0f, 0.0f}, {0.0f, 1.0f}}
#define GLM_MAT2_ZERO_INIT {{0.0f, 0.0f}, {0.0f, 0.0f}} #define GLM_MAT2_ZERO_INIT {{0.0f, 0.0f}, {0.0f, 0.0f}}
@@ -132,7 +136,9 @@ glm_mat2_zero(mat2 mat) {
CGLM_INLINE CGLM_INLINE
void void
glm_mat2_mul(mat2 m1, mat2 m2, mat2 dest) { glm_mat2_mul(mat2 m1, mat2 m2, mat2 dest) {
#if defined( __SSE__ ) || defined( __SSE2__ ) #if defined(__wasm__) && defined(__wasm_simd128__)
glm_mat2_mul_wasm(m1, m2, dest);
#elif defined( __SSE__ ) || defined( __SSE2__ )
glm_mat2_mul_sse2(m1, m2, dest); glm_mat2_mul_sse2(m1, m2, dest);
#elif defined(CGLM_NEON_FP) #elif defined(CGLM_NEON_FP)
glm_mat2_mul_neon(m1, m2, dest); glm_mat2_mul_neon(m1, m2, dest);
@@ -160,7 +166,9 @@ glm_mat2_mul(mat2 m1, mat2 m2, mat2 dest) {
CGLM_INLINE CGLM_INLINE
void void
glm_mat2_transpose_to(mat2 m, mat2 dest) { glm_mat2_transpose_to(mat2 m, mat2 dest) {
#if defined( __SSE__ ) || defined( __SSE2__ ) #if defined(__wasm__) && defined(__wasm_simd128__)
glm_mat2_transp_wasm(m, dest);
#elif defined( __SSE__ ) || defined( __SSE2__ )
glm_mat2_transp_sse2(m, dest); glm_mat2_transp_sse2(m, dest);
#else #else
dest[0][0] = m[0][0]; dest[0][0] = m[0][0];
@@ -222,7 +230,10 @@ glm_mat2_trace(mat2 m) {
CGLM_INLINE CGLM_INLINE
void void
glm_mat2_scale(mat2 m, float s) { glm_mat2_scale(mat2 m, float s) {
#if defined( __SSE__ ) || defined( __SSE2__ ) #if defined(__wasm__) && defined(__wasm_simd128__)
glmm_store(m[0], wasm_f32x4_mul(wasm_v128_load(m[0]),
wasm_f32x4_splat(s)));
#elif defined( __SSE__ ) || defined( __SSE2__ )
glmm_store(m[0], _mm_mul_ps(_mm_loadu_ps(m[0]), _mm_set1_ps(s))); glmm_store(m[0], _mm_mul_ps(_mm_loadu_ps(m[0]), _mm_set1_ps(s)));
#elif defined(CGLM_NEON_FP) #elif defined(CGLM_NEON_FP)
vst1q_f32(m[0], vmulq_f32(vld1q_f32(m[0]), vdupq_n_f32(s))); vst1q_f32(m[0], vmulq_f32(vld1q_f32(m[0]), vdupq_n_f32(s)));

View File

@@ -42,6 +42,10 @@
# include "simd/sse2/mat3.h" # include "simd/sse2/mat3.h"
#endif #endif
#ifdef CGLM_SIMD_WASM
# include "simd/wasm/mat3.h"
#endif
#define GLM_MAT3_IDENTITY_INIT {{1.0f, 0.0f, 0.0f}, \ #define GLM_MAT3_IDENTITY_INIT {{1.0f, 0.0f, 0.0f}, \
{0.0f, 1.0f, 0.0f}, \ {0.0f, 1.0f, 0.0f}, \
{0.0f, 0.0f, 1.0f}} {0.0f, 0.0f, 1.0f}}
@@ -148,7 +152,9 @@ glm_mat3_zero(mat3 mat) {
CGLM_INLINE CGLM_INLINE
void void
glm_mat3_mul(mat3 m1, mat3 m2, mat3 dest) { glm_mat3_mul(mat3 m1, mat3 m2, mat3 dest) {
#if defined( __SSE__ ) || defined( __SSE2__ ) #if defined(__wasm__) && defined(__wasm_simd128__)
glm_mat3_mul_wasm(m1, m2, dest);
#elif defined( __SSE__ ) || defined( __SSE2__ )
glm_mat3_mul_sse2(m1, m2, dest); glm_mat3_mul_sse2(m1, m2, dest);
#else #else
float a00 = m1[0][0], a01 = m1[0][1], a02 = m1[0][2], float a00 = m1[0][0], a01 = m1[0][1], a02 = m1[0][2],

View File

@@ -64,6 +64,10 @@
# include "simd/neon/mat4.h" # include "simd/neon/mat4.h"
#endif #endif
#ifdef CGLM_SIMD_WASM
# include "simd/wasm/mat4.h"
#endif
#ifdef DEBUG #ifdef DEBUG
# include <assert.h> # include <assert.h>
#endif #endif
@@ -121,7 +125,12 @@ glm_mat4_ucopy(mat4 mat, mat4 dest) {
CGLM_INLINE CGLM_INLINE
void void
glm_mat4_copy(mat4 mat, mat4 dest) { glm_mat4_copy(mat4 mat, mat4 dest) {
#ifdef __AVX__ #if defined(__wasm__) && defined(__wasm_simd128__)
glmm_store(dest[0], glmm_load(mat[0]));
glmm_store(dest[1], glmm_load(mat[1]));
glmm_store(dest[2], glmm_load(mat[2]));
glmm_store(dest[3], glmm_load(mat[3]));
#elif defined(__AVX__)
glmm_store256(dest[0], glmm_load256(mat[0])); glmm_store256(dest[0], glmm_load256(mat[0]));
glmm_store256(dest[2], glmm_load256(mat[2])); glmm_store256(dest[2], glmm_load256(mat[2]));
#elif defined( __SSE__ ) || defined( __SSE2__ ) #elif defined( __SSE__ ) || defined( __SSE2__ )
@@ -187,7 +196,14 @@ glm_mat4_identity_array(mat4 * __restrict mat, size_t count) {
CGLM_INLINE CGLM_INLINE
void void
glm_mat4_zero(mat4 mat) { glm_mat4_zero(mat4 mat) {
#ifdef __AVX__ #if defined(__wasm__) && defined(__wasm_simd128__)
glmm_128 x0;
x0 = wasm_f32x4_const_splat(0.f);
glmm_store(mat[0], x0);
glmm_store(mat[1], x0);
glmm_store(mat[2], x0);
glmm_store(mat[3], x0);
#elif defined(__AVX__)
__m256 y0; __m256 y0;
y0 = _mm256_setzero_ps(); y0 = _mm256_setzero_ps();
glmm_store256(mat[0], y0); glmm_store256(mat[0], y0);
@@ -297,7 +313,9 @@ glm_mat4_ins3(mat3 mat, mat4 dest) {
CGLM_INLINE CGLM_INLINE
void void
glm_mat4_mul(mat4 m1, mat4 m2, mat4 dest) { glm_mat4_mul(mat4 m1, mat4 m2, mat4 dest) {
#ifdef __AVX__ #if defined(__wasm__) && defined(__wasm_simd128__)
glm_mat4_mul_wasm(m1, m2, dest);
#elif defined(__AVX__)
glm_mat4_mul_avx(m1, m2, dest); glm_mat4_mul_avx(m1, m2, dest);
#elif defined( __SSE__ ) || defined( __SSE2__ ) #elif defined( __SSE__ ) || defined( __SSE2__ )
glm_mat4_mul_sse2(m1, m2, dest); glm_mat4_mul_sse2(m1, m2, dest);
@@ -377,7 +395,9 @@ glm_mat4_mulN(mat4 * __restrict matrices[], uint32_t len, mat4 dest) {
CGLM_INLINE CGLM_INLINE
void void
glm_mat4_mulv(mat4 m, vec4 v, vec4 dest) { glm_mat4_mulv(mat4 m, vec4 v, vec4 dest) {
#if defined( __SSE__ ) || defined( __SSE2__ ) #if defined(__wasm__) && defined(__wasm_simd128__)
glm_mat4_mulv_wasm(m, v, dest);
#elif defined( __SSE__ ) || defined( __SSE2__ )
glm_mat4_mulv_sse2(m, v, dest); glm_mat4_mulv_sse2(m, v, dest);
#elif defined(CGLM_NEON_FP) #elif defined(CGLM_NEON_FP)
glm_mat4_mulv_neon(m, v, dest); glm_mat4_mulv_neon(m, v, dest);
@@ -497,7 +517,9 @@ glm_mat4_mulv3(mat4 m, vec3 v, float last, vec3 dest) {
CGLM_INLINE CGLM_INLINE
void void
glm_mat4_transpose_to(mat4 m, mat4 dest) { glm_mat4_transpose_to(mat4 m, mat4 dest) {
#if defined( __SSE__ ) || defined( __SSE2__ ) #if defined(__wasm__) && defined(__wasm_simd128__)
glm_mat4_transp_wasm(m, dest);
#elif defined( __SSE__ ) || defined( __SSE2__ )
glm_mat4_transp_sse2(m, dest); glm_mat4_transp_sse2(m, dest);
#elif defined(CGLM_NEON_FP) #elif defined(CGLM_NEON_FP)
glm_mat4_transp_neon(m, dest); glm_mat4_transp_neon(m, dest);
@@ -521,7 +543,9 @@ glm_mat4_transpose_to(mat4 m, mat4 dest) {
CGLM_INLINE CGLM_INLINE
void void
glm_mat4_transpose(mat4 m) { glm_mat4_transpose(mat4 m) {
#if defined( __SSE__ ) || defined( __SSE2__ ) #if defined(__wasm__) && defined(__wasm_simd128__)
glm_mat4_transp_wasm(m, m);
#elif defined( __SSE__ ) || defined( __SSE2__ )
glm_mat4_transp_sse2(m, m); glm_mat4_transp_sse2(m, m);
#elif defined(CGLM_NEON_FP) #elif defined(CGLM_NEON_FP)
glm_mat4_transp_neon(m, m); glm_mat4_transp_neon(m, m);
@@ -560,7 +584,9 @@ glm_mat4_scale_p(mat4 m, float s) {
CGLM_INLINE CGLM_INLINE
void void
glm_mat4_scale(mat4 m, float s) { glm_mat4_scale(mat4 m, float s) {
#ifdef __AVX__ #if defined(__wasm__) && defined(__wasm_simd128__)
glm_mat4_scale_wasm(m, s);
#elif defined(__AVX__)
glm_mat4_scale_avx(m, s); glm_mat4_scale_avx(m, s);
#elif defined( __SSE__ ) || defined( __SSE2__ ) #elif defined( __SSE__ ) || defined( __SSE2__ )
glm_mat4_scale_sse2(m, s); glm_mat4_scale_sse2(m, s);
@@ -581,7 +607,9 @@ glm_mat4_scale(mat4 m, float s) {
CGLM_INLINE CGLM_INLINE
float float
glm_mat4_det(mat4 mat) { glm_mat4_det(mat4 mat) {
#if defined( __SSE__ ) || defined( __SSE2__ ) #if defined(__wasm__) && defined(__wasm_simd128__)
return glm_mat4_det_wasm(mat);
#elif defined( __SSE__ ) || defined( __SSE2__ )
return glm_mat4_det_sse2(mat); return glm_mat4_det_sse2(mat);
#elif defined(CGLM_NEON_FP) #elif defined(CGLM_NEON_FP)
return glm_mat4_det_neon(mat); return glm_mat4_det_neon(mat);
@@ -679,7 +707,9 @@ glm_mat4_inv(mat4 mat, mat4 dest) {
CGLM_INLINE CGLM_INLINE
void void
glm_mat4_inv_fast(mat4 mat, mat4 dest) { glm_mat4_inv_fast(mat4 mat, mat4 dest) {
#if defined( __SSE__ ) || defined( __SSE2__ ) #if defined(__wasm__) && defined(__wasm_simd128__)
glm_mat4_inv_fast_wasm(mat, dest);
#elif defined( __SSE__ ) || defined( __SSE2__ )
glm_mat4_inv_fast_sse2(mat, dest); glm_mat4_inv_fast_sse2(mat, dest);
#else #else
glm_mat4_inv(mat, dest); glm_mat4_inv(mat, dest);

View File

@@ -70,6 +70,10 @@
# include "simd/neon/quat.h" # include "simd/neon/quat.h"
#endif #endif
#ifdef CGLM_SIMD_WASM
# include "simd/wasm/quat.h"
#endif
CGLM_INLINE void glm_quat_normalize(versor q); CGLM_INLINE void glm_quat_normalize(versor q);
/* /*
@@ -238,7 +242,22 @@ glm_quat_norm(versor q) {
CGLM_INLINE CGLM_INLINE
void void
glm_quat_normalize_to(versor q, versor dest) { glm_quat_normalize_to(versor q, versor dest) {
#if defined( __SSE2__ ) || defined( __SSE2__ ) #if defined(__wasm__) && defined(__wasm_simd128__)
glmm_128 xdot, x0;
float dot;
x0 = glmm_load(q);
xdot = glmm_vdot(x0, x0);
/* dot = _mm_cvtss_f32(xdot); */
dot = wasm_f32x4_extract_lane(xdot, 0);
if (dot <= 0.0f) {
glm_quat_identity(dest);
return;
}
glmm_store(dest, wasm_f32x4_div(x0, wasm_f32x4_sqrt(xdot)));
#elif defined( __SSE2__ ) || defined( __SSE2__ )
__m128 xdot, x0; __m128 xdot, x0;
float dot; float dot;
@@ -438,7 +457,9 @@ glm_quat_mul(versor p, versor q, versor dest) {
+ (a1 d2 + b1 c2 c1 b2 + d1 a2)k + (a1 d2 + b1 c2 c1 b2 + d1 a2)k
a1 a2 b1 b2 c1 c2 d1 d2 a1 a2 b1 b2 c1 c2 d1 d2
*/ */
#if defined( __SSE__ ) || defined( __SSE2__ ) #if defined(__wasm__) && defined(__wasm_simd128__)
glm_quat_mul_wasm(p, q, dest);
#elif defined( __SSE__ ) || defined( __SSE2__ )
glm_quat_mul_sse2(p, q, dest); glm_quat_mul_sse2(p, q, dest);
#elif defined(CGLM_NEON_FP) #elif defined(CGLM_NEON_FP)
glm_quat_mul_neon(p, q, dest); glm_quat_mul_neon(p, q, dest);

View File

@@ -52,6 +52,10 @@ glmm_float32x4_init(float x, float y, float z, float w) {
# define glmm_float32x4_init(x, y, z, w) { x, y, z, w } # define glmm_float32x4_init(x, y, z, w) { x, y, z, w }
#endif #endif
#define glmm_float32x4_SIGNMASK_PNPN glmm_float32x4_init( 0.f, -0.f, 0.f, -0.f)
#define glmm_float32x4_SIGNMASK_NPNP glmm_float32x4_init(-0.f, 0.f, -0.f, 0.f)
#define glmm_float32x4_SIGNMASK_NPPN glmm_float32x4_init(-0.f, 0.f, 0.f, -0.f)
static inline static inline
float32x4_t float32x4_t
glmm_abs(float32x4_t v) { glmm_abs(float32x4_t v) {

View File

@@ -99,13 +99,20 @@
# endif # endif
#endif #endif
#if defined(CGLM_SIMD_x86) || defined(CGLM_SIMD_ARM) /* WebAssembly */
#if defined(__wasm__) && defined(__wasm_simd128__)
# ifndef CGLM_SIMD_WASM
# define CGLM_SIMD_WASM
# endif
#endif
#if defined(CGLM_SIMD_x86) || defined(CGLM_SIMD_ARM) || defined(CGLM_SIMD_WASM)
# ifndef CGLM_SIMD # ifndef CGLM_SIMD
# define CGLM_SIMD # define CGLM_SIMD
# endif # endif
#endif #endif
#if defined(CGLM_SIMD_x86) #if defined(CGLM_SIMD_x86) && !defined(CGLM_SIMD_WASM)
# include "x86.h" # include "x86.h"
#endif #endif
@@ -113,4 +120,8 @@
# include "arm.h" # include "arm.h"
#endif #endif
#if defined(CGLM_SIMD_WASM)
# include "wasm.h"
#endif
#endif /* cglm_intrin_h */ #endif /* cglm_intrin_h */

View File

@@ -108,7 +108,7 @@ glm_mat4_det_neon(mat4 mat) {
float32x4_t r0, r1, r2, r3, x0, x1, x2; float32x4_t r0, r1, r2, r3, x0, x1, x2;
float32x2_t ij, op, mn, kl, nn, mm, jj, ii, gh, ef, t12, t34; float32x2_t ij, op, mn, kl, nn, mm, jj, ii, gh, ef, t12, t34;
float32x4x2_t a1; float32x4x2_t a1;
float32x4_t x3 = glmm_float32x4_init(0.f, -0.f, 0.f, -0.f); float32x4_t x3 = glmm_float32x4_SIGNMASK_PNPN;
/* 127 <- 0, [square] det(A) = det(At) */ /* 127 <- 0, [square] det(A) = det(At) */
r0 = glmm_load(mat[0]); /* d c b a */ r0 = glmm_load(mat[0]); /* d c b a */
@@ -181,7 +181,7 @@ glm_mat4_inv_neon(mat4 mat, mat4 dest) {
x0, x1, x2, x3, x4, x5, x6, x7, x8; x0, x1, x2, x3, x4, x5, x6, x7, x8;
float32x4x2_t a1; float32x4x2_t a1;
float32x2_t lp, ko, hg, jn, im, fe, ae, bf, cg, dh; float32x2_t lp, ko, hg, jn, im, fe, ae, bf, cg, dh;
float32x4_t x9 = glmm_float32x4_init(-0.f, 0.f, -0.f, 0.f); float32x4_t x9 = glmm_float32x4_SIGNMASK_NPNP;
x8 = vrev64q_f32(x9); x8 = vrev64q_f32(x9);

View File

@@ -23,7 +23,8 @@ glm_quat_mul_neon(versor p, versor q, versor dest) {
*/ */
glmm_128 xp, xq, xqr, r, x, y, z, s2, s3; glmm_128 xp, xq, xqr, r, x, y, z, s2, s3;
glmm_128 s1 = glmm_float32x4_init(-0.f, 0.f, 0.f, -0.f); glmm_128 s1 = glmm_float32x4_SIGNMASK_NPPN;
float32x2_t qh, ql; float32x2_t qh, ql;
xp = glmm_load(p); /* 3 2 1 0 */ xp = glmm_load(p); /* 3 2 1 0 */

View File

@@ -98,7 +98,7 @@ glm_inv_tr_sse2(mat4 mat) {
x2 = glmm_shuff1(r3, 0, 0, 0, 0); x2 = glmm_shuff1(r3, 0, 0, 0, 0);
x3 = glmm_shuff1(r3, 1, 1, 1, 1); x3 = glmm_shuff1(r3, 1, 1, 1, 1);
x4 = glmm_shuff1(r3, 2, 2, 2, 2); x4 = glmm_shuff1(r3, 2, 2, 2, 2);
x5 = _mm_set1_ps(-0.f); x5 = glmm_float32x4_SIGNMASK_NEG;
x0 = glmm_fmadd(r0, x2, glmm_fmadd(r1, x3, _mm_mul_ps(r2, x4))); x0 = glmm_fmadd(r0, x2, glmm_fmadd(r1, x3, _mm_mul_ps(r2, x4)));
x0 = _mm_xor_ps(x0, x5); x0 = _mm_xor_ps(x0, x5);

View File

@@ -153,7 +153,7 @@ glm_mat4_det_sse2(mat4 mat) {
_mm_shuffle_ps(x0, x1, _MM_SHUFFLE(2, 2, 3, 1)), _mm_shuffle_ps(x0, x1, _MM_SHUFFLE(2, 2, 3, 1)),
x2); x2);
x2 = _mm_xor_ps(x2, _mm_set_ps(-0.f, 0.f, -0.f, 0.f)); x2 = _mm_xor_ps(x2, glmm_float32x4_SIGNMASK_NPNP);
return glmm_hadd(_mm_mul_ps(x2, r0)); return glmm_hadd(_mm_mul_ps(x2, r0));
} }
@@ -166,7 +166,8 @@ glm_mat4_inv_fast_sse2(mat4 mat, mat4 dest) {
t0, t1, t2, t3, t4, t5, t0, t1, t2, t3, t4, t5,
x0, x1, x2, x3, x4, x5, x6, x7, x8, x9; x0, x1, x2, x3, x4, x5, x6, x7, x8, x9;
x8 = _mm_set_ps(-0.f, 0.f, -0.f, 0.f); /* x8 = _mm_set_ps(-0.f, 0.f, -0.f, 0.f); */
x8 = glmm_float32x4_SIGNMASK_NPNP;
x9 = glmm_shuff1(x8, 2, 1, 2, 1); x9 = glmm_shuff1(x8, 2, 1, 2, 1);
/* 127 <- 0 */ /* 127 <- 0 */
@@ -302,7 +303,8 @@ glm_mat4_inv_sse2(mat4 mat, mat4 dest) {
t0, t1, t2, t3, t4, t5, t0, t1, t2, t3, t4, t5,
x0, x1, x2, x3, x4, x5, x6, x7, x8, x9; x0, x1, x2, x3, x4, x5, x6, x7, x8, x9;
x8 = _mm_set_ps(-0.f, 0.f, -0.f, 0.f); /* x8 = _mm_set_ps(-0.f, 0.f, -0.f, 0.f); */
x8 = glmm_float32x4_SIGNMASK_NPNP;
x9 = glmm_shuff1(x8, 2, 1, 2, 1); x9 = glmm_shuff1(x8, 2, 1, 2, 1);
/* 127 <- 0 */ /* 127 <- 0 */

View File

@@ -26,7 +26,7 @@ glm_quat_mul_sse2(versor p, versor q, versor dest) {
xp = glmm_load(p); /* 3 2 1 0 */ xp = glmm_load(p); /* 3 2 1 0 */
xq = glmm_load(q); xq = glmm_load(q);
x1 = _mm_set_ps(-0.f, 0.f, -0.f, 0.f); /* TODO: _mm_set1_ss() + shuff ? */ x1 = glmm_float32x4_SIGNMASK_NPNP; /* TODO: _mm_set1_ss() + shuff ? */
r = _mm_mul_ps(glmm_splat_w(xp), xq); r = _mm_mul_ps(glmm_splat_w(xp), xq);
x2 = _mm_unpackhi_ps(x1, x1); x2 = _mm_unpackhi_ps(x1, x1);

198
include/cglm/simd/wasm.h Normal file
View File

@@ -0,0 +1,198 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#ifndef cglm_simd_wasm_h
#define cglm_simd_wasm_h
#include "intrin.h"
#ifdef CGLM_SIMD_WASM
#include <wasm_simd128.h>
#define glmm_load(p) wasm_v128_load(p)
#define glmm_store(p, a) wasm_v128_store(p, (a))
#define glmm_set1(x) wasm_f32x4_splat(x)
#define glmm_128 v128_t
#define glmm_shuff1(xmm, z, y, x, w) wasm_i32x4_shuffle(xmm, xmm, w, x, y, z)
#define glmm_splat(x, lane) glmm_shuff1(x, lane, lane, lane, lane)
#define glmm_splat_x(x) glmm_splat(x, 0)
#define glmm_splat_y(x) glmm_splat(x, 1)
#define glmm_splat_z(x) glmm_splat(x, 2)
#define glmm_splat_w(x) glmm_splat(x, 3)
#define GLMM_NEGZEROf 0x80000000 /* 0x80000000 ---> -0.0f */
/* _mm_set_ps(X, Y, Z, W); */
#define GLMM__SIGNMASKf(X, Y, Z, W) wasm_i32x4_const(X, Y, Z, W)
#define glmm_float32x4_SIGNMASK_PNPN GLMM__SIGNMASKf(0, GLMM_NEGZEROf, 0, GLMM_NEGZEROf)
#define glmm_float32x4_SIGNMASK_NPNP GLMM__SIGNMASKf(GLMM_NEGZEROf, 0, GLMM_NEGZEROf, 0)
#define glmm_float32x4_SIGNMASK_NPPN GLMM__SIGNMASKf(GLMM_NEGZEROf, 0, 0, GLMM_NEGZEROf)
#define glmm_float32x4_SIGNMASK_NEG wasm_i32x4_const_splat(GLMM_NEGZEROf)
static inline
glmm_128
glmm_abs(glmm_128 x) {
return wasm_f32x4_abs(x);
}
static inline
glmm_128
glmm_vhadd(glmm_128 v) {
glmm_128 x0;
x0 = wasm_f32x4_add(v, glmm_shuff1(v, 0, 1, 2, 3));
x0 = wasm_f32x4_add(x0, glmm_shuff1(x0, 1, 0, 0, 1));
return x0;
}
static inline
glmm_128
glmm_vhadds(glmm_128 v) {
glmm_128 shuf, sums;
shuf = glmm_shuff1(v, 2, 3, 0, 1);
sums = wasm_f32x4_add(v, shuf);
/* shuf = _mm_movehl_ps(shuf, sums); */
shuf = wasm_i32x4_shuffle(shuf, sums, 6, 7, 2, 3);
sums = wasm_i32x4_shuffle(sums, wasm_f32x4_add(sums, shuf), 4, 1, 2, 3);
return sums;
}
static inline
float
glmm_hadd(glmm_128 v) {
return wasm_f32x4_extract_lane(glmm_vhadds(v), 0);
}
static inline
glmm_128
glmm_vhmin(glmm_128 v) {
glmm_128 x0, x1, x2;
x0 = glmm_shuff1(v, 2, 3, 2, 3); /* [2, 3, 2, 3] */
x1 = wasm_f32x4_pmin(x0, v); /* [0|2, 1|3, 2|2, 3|3] */
x2 = glmm_splat(x1, 1); /* [1|3, 1|3, 1|3, 1|3] */
return wasm_f32x4_pmin(x1, x2);
}
static inline
float
glmm_hmin(glmm_128 v) {
return wasm_f32x4_extract_lane(glmm_vhmin(v), 0);
}
static inline
glmm_128
glmm_vhmax(glmm_128 v) {
glmm_128 x0, x1, x2;
x0 = glmm_shuff1(v, 2, 3, 2, 3); /* [2, 3, 2, 3] */
x1 = wasm_f32x4_pmax(x0, v); /* [0|2, 1|3, 2|2, 3|3] */
x2 = glmm_splat(x1, 1); /* [1|3, 1|3, 1|3, 1|3] */
/* _mm_max_ss */
return wasm_i32x4_shuffle(x1, wasm_f32x4_pmax(x1, x2), 4, 1, 2, 3);
}
static inline
float
glmm_hmax(glmm_128 v) {
return wasm_f32x4_extract_lane(glmm_vhmax(v), 0);
}
static inline
glmm_128
glmm_vdots(glmm_128 a, glmm_128 b) {
return glmm_vhadds(wasm_f32x4_mul(a, b));
}
static inline
glmm_128
glmm_vdot(glmm_128 a, glmm_128 b) {
glmm_128 x0;
x0 = wasm_f32x4_mul(a, b);
x0 = wasm_f32x4_add(x0, glmm_shuff1(x0, 1, 0, 3, 2));
return wasm_f32x4_add(x0, glmm_shuff1(x0, 0, 1, 0, 1));
}
static inline
float
glmm_dot(glmm_128 a, glmm_128 b) {
return wasm_f32x4_extract_lane(glmm_vdots(a, b), 0);
}
static inline
float
glmm_norm(glmm_128 a) {
glmm_128 x0;
x0 = glmm_vhadds(wasm_f32x4_mul(a, a));
return wasm_f32x4_extract_lane(
wasm_i32x4_shuffle(x0, wasm_f32x4_sqrt(x0),4, 1, 2, 3), 0);
}
static inline
float
glmm_norm2(glmm_128 a) {
return wasm_f32x4_extract_lane(glmm_vhadds(wasm_f32x4_mul(a, a)), 0);
}
static inline
float
glmm_norm_one(glmm_128 a) {
return wasm_f32x4_extract_lane(glmm_vhadds(glmm_abs(a)), 0);
}
static inline
float
glmm_norm_inf(glmm_128 a) {
return wasm_f32x4_extract_lane(glmm_vhmax(glmm_abs(a)), 0);
}
static inline
glmm_128
glmm_load3(float v[3]) {
glmm_128 xy = wasm_v128_load64_zero(v);
return wasm_f32x4_replace_lane(xy, 2, v[2]);
}
static inline
void
glmm_store3(float v[3], glmm_128 vx) {
wasm_v128_store64_lane(v, vx, 0);
wasm_v128_store32_lane(&v[2], vx, 2);
}
static inline
glmm_128
glmm_div(glmm_128 a, glmm_128 b) {
return wasm_f32x4_div(a, b);
}
static inline
glmm_128
glmm_fmadd(glmm_128 a, glmm_128 b, glmm_128 c) {
return wasm_f32x4_add(c, wasm_f32x4_mul(a, b));
}
static inline
glmm_128
glmm_fnmadd(glmm_128 a, glmm_128 b, glmm_128 c) {
return wasm_f32x4_sub(c, wasm_f32x4_mul(a, b));
}
static inline
glmm_128
glmm_fmsub(glmm_128 a, glmm_128 b, glmm_128 c) {
return wasm_f32x4_sub(wasm_f32x4_mul(a, b), c);
}
static inline
glmm_128
glmm_fnmsub(glmm_128 a, glmm_128 b, glmm_128 c) {
return wasm_f32x4_neg(wasm_f32x4_add(wasm_f32x4_mul(a, b), c));
}
#endif
#endif /* cglm_simd_wasm_h */

View File

@@ -0,0 +1,127 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#ifndef cglm_affine_mat_wasm_h
#define cglm_affine_mat_wasm_h
#if defined(__wasm__) && defined(__wasm_simd128__)
#include "../../common.h"
#include "../intrin.h"
CGLM_INLINE
void
glm_mul_wasm(mat4 m1, mat4 m2, mat4 dest) {
/* D = R * L (Column-Major) */
glmm_128 l, r0, r1, r2, r3, v0, v1, v2, v3;
l = glmm_load(m1[0]);
r0 = glmm_load(m2[0]);
r1 = glmm_load(m2[1]);
r2 = glmm_load(m2[2]);
r3 = glmm_load(m2[3]);
v0 = wasm_f32x4_mul(glmm_splat_x(r0), l);
v1 = wasm_f32x4_mul(glmm_splat_x(r1), l);
v2 = wasm_f32x4_mul(glmm_splat_x(r2), l);
v3 = wasm_f32x4_mul(glmm_splat_x(r3), l);
l = glmm_load(m1[1]);
v0 = glmm_fmadd(glmm_splat_y(r0), l, v0);
v1 = glmm_fmadd(glmm_splat_y(r1), l, v1);
v2 = glmm_fmadd(glmm_splat_y(r2), l, v2);
v3 = glmm_fmadd(glmm_splat_y(r3), l, v3);
l = glmm_load(m1[2]);
v0 = glmm_fmadd(glmm_splat_z(r0), l, v0);
v1 = glmm_fmadd(glmm_splat_z(r1), l, v1);
v2 = glmm_fmadd(glmm_splat_z(r2), l, v2);
v3 = glmm_fmadd(glmm_splat_z(r3), l, v3);
l = glmm_load(m1[3]);
v3 = glmm_fmadd(glmm_splat_w(r3), l, v3);
glmm_store(dest[0], v0);
glmm_store(dest[1], v1);
glmm_store(dest[2], v2);
glmm_store(dest[3], v3);
}
CGLM_INLINE
void
glm_mul_rot_wasm(mat4 m1, mat4 m2, mat4 dest) {
/* D = R * L (Column-Major) */
glmm_128 l, r0, r1, r2, v0, v1, v2;
l = glmm_load(m1[0]);
r0 = glmm_load(m2[0]);
r1 = glmm_load(m2[1]);
r2 = glmm_load(m2[2]);
v0 = wasm_f32x4_mul(glmm_splat_x(r0), l);
v1 = wasm_f32x4_mul(glmm_splat_x(r1), l);
v2 = wasm_f32x4_mul(glmm_splat_x(r2), l);
l = glmm_load(m1[1]);
v0 = glmm_fmadd(glmm_splat_y(r0), l, v0);
v1 = glmm_fmadd(glmm_splat_y(r1), l, v1);
v2 = glmm_fmadd(glmm_splat_y(r2), l, v2);
l = glmm_load(m1[2]);
v0 = glmm_fmadd(glmm_splat_z(r0), l, v0);
v1 = glmm_fmadd(glmm_splat_z(r1), l, v1);
v2 = glmm_fmadd(glmm_splat_z(r2), l, v2);
glmm_store(dest[0], v0);
glmm_store(dest[1], v1);
glmm_store(dest[2], v2);
glmm_store(dest[3], glmm_load(m1[3]));
}
CGLM_INLINE
void
glm_inv_tr_wasm(mat4 mat) {
glmm_128 r0, r1, r2, r3, x0, x1, x2, x3, x4, x5;
r0 = glmm_load(mat[0]);
r1 = glmm_load(mat[1]);
r2 = glmm_load(mat[2]);
r3 = glmm_load(mat[3]);
x1 = wasm_f32x4_const(0.0f, 0.0f, 0.0f, 1.0f);
/* _MM_TRANSPOSE4_PS(r0, r1, r2, x1); */
x2 = wasm_i32x4_shuffle(r0, r1, 0, 4, 1, 5);
x3 = wasm_i32x4_shuffle(r0, r1, 2, 6, 3, 7);
x4 = wasm_i32x4_shuffle(r2, x1, 0, 4, 1, 5);
x5 = wasm_i32x4_shuffle(r2, x1, 2, 6, 3, 7);
/* r0 = _mm_movelh_ps(x2, x4); */
r0 = wasm_i32x4_shuffle(x2, x4, 0, 1, 4, 5);
/* r1 = _mm_movehl_ps(x4, x2); */
r1 = wasm_i32x4_shuffle(x4, x2, 6, 7, 2, 3);
/* r2 = _mm_movelh_ps(x3, x5); */
r2 = wasm_i32x4_shuffle(x3, x5, 0, 1, 4, 5);
/* x1 = _mm_movehl_ps(x5, x3); */
x1 = wasm_i32x4_shuffle(x5, x3, 6, 7, 2, 3);
x2 = glmm_shuff1(r3, 0, 0, 0, 0);
x3 = glmm_shuff1(r3, 1, 1, 1, 1);
x4 = glmm_shuff1(r3, 2, 2, 2, 2);
x0 = glmm_fmadd(r0, x2,
glmm_fmadd(r1, x3, wasm_f32x4_mul(r2, x4)));
x0 = wasm_f32x4_neg(x0);
x0 = wasm_f32x4_add(x0, x1);
glmm_store(mat[0], r0);
glmm_store(mat[1], r1);
glmm_store(mat[2], r2);
glmm_store(mat[3], x0);
}
#endif
#endif /* cglm_affine_mat_wasm_h */

View File

@@ -0,0 +1,50 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#ifndef cglm_mat2_wasm_h
#define cglm_mat2_wasm_h
#if defined(__wasm__) && defined(__wasm_simd128__)
#include "../../common.h"
#include "../intrin.h"
CGLM_INLINE
void
glm_mat2_mul_wasm(mat2 m1, mat2 m2, mat2 dest) {
glmm_128 x0, x1, x2, x3, x4;
x1 = glmm_load(m1[0]); /* d c b a */
x2 = glmm_load(m2[0]); /* h g f e */
x3 = glmm_shuff1(x2, 2, 2, 0, 0);
x4 = glmm_shuff1(x2, 3, 3, 1, 1);
/* x0 = _mm_movelh_ps(x1, x1); */
x0 = wasm_i32x4_shuffle(x1, x1, 0, 1, 4, 5);
/* x2 = _mm_movehl_ps(x1, x1); */
x2 = wasm_i32x4_shuffle(x1, x1, 6, 7, 2, 3);
/*
dest[0][0] = a * e + c * f;
dest[0][1] = b * e + d * f;
dest[1][0] = a * g + c * h;
dest[1][1] = b * g + d * h;
*/
x0 = glmm_fmadd(x0, x3, wasm_f32x4_mul(x2, x4));
glmm_store(dest[0], x0);
}
CGLM_INLINE
void
glm_mat2_transp_wasm(mat2 m, mat2 dest) {
/* d c b a */
/* d b c a */
glmm_store(dest[0], glmm_shuff1(glmm_load(m[0]), 3, 1, 2, 0));
}
#endif
#endif /* cglm_mat2_wasm_h */

View File

@@ -0,0 +1,85 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#ifndef cglm_mat3_wasm_h
#define cglm_mat3_wasm_h
#if defined(__wasm__) && defined(__wasm_simd128__)
#include "../../common.h"
#include "../intrin.h"
CGLM_INLINE
void
glm_mat3_mul_wasm(mat3 m1, mat3 m2, mat3 dest) {
glmm_128 l0, l1, l2, r0, r1, r2, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9;
l0 = wasm_v128_load(m1[0]);
l1 = wasm_v128_load(&m1[1][1]);
r0 = wasm_v128_load(m2[0]);
r1 = wasm_v128_load(&m2[1][1]);
x8 = glmm_shuff1(l0, 0, 2, 1, 0); /* a00 a02 a01 a00 */
x1 = glmm_shuff1(r0, 3, 0, 0, 0); /* b10 b00 b00 b00 */
x2 = wasm_i32x4_shuffle(l0, l1, 3, 3, 4, 5); /* a12 a11 a10 a10 */
x3 = wasm_i32x4_shuffle(r0, r1, 1, 3, 4, 6); /* b20 b11 b10 b01 */
x0 = wasm_f32x4_mul(x8, x1);
x6 = glmm_shuff1(l0, 1, 0, 2, 1); /* a01 a00 a02 a01 */
x7 = glmm_shuff1(x3, 3, 3, 1, 1); /* b20 b20 b10 b10 */
l2 = wasm_v128_load32_zero(&m1[2][2]);
r2 = wasm_v128_load32_zero(&m2[2][2]);
x1 = wasm_f32x4_mul(x6, x7);
l2 = glmm_shuff1(l2, 0, 0, 1, 0); /* a22 a22 0.f a22 */
r2 = glmm_shuff1(r2, 0, 0, 1, 0); /* b22 b22 0.f b22 */
x4 = glmm_shuff1(x2, 0, 3, 2, 0); /* a10 a12 a11 a10 */
x5 = glmm_shuff1(x2, 2, 0, 3, 2); /* a11 a10 a12 a11 */
x6 = glmm_shuff1(x3, 2, 0, 0, 0); /* b11 b01 b01 b01 */
x2 = glmm_shuff1(r1, 3, 3, 0, 0); /* b21 b21 b11 b11 */
/* x8 = _mm_unpackhi_ps(x8, x4); */
/* x9 = _mm_unpackhi_ps(x7, x2); */
x8 = wasm_i32x4_shuffle(x8, x4, 2, 6, 3, 7); /* a10 a00 a12 a02 */
x9 = wasm_i32x4_shuffle(x7, x2, 2, 6, 3, 7); /* b21 b20 b21 b20 */
x0 = glmm_fmadd(x4, x6, x0);
x1 = glmm_fmadd(x5, x2, x1);
/* x2 = _mm_movehl_ps(l2, l1); */
x2 = wasm_i32x4_shuffle(l2, l1, 6, 7, 2, 3); /* a22 a22 a21 a20 */
x3 = glmm_shuff1(x2, 0, 2, 1, 0); /* a20 a22 a21 a20 */
x2 = glmm_shuff1(x2, 1, 0, 2, 1); /* a21 a20 a22 a21 */
x4 = wasm_i32x4_shuffle(r0, r1, 2, 2, 5, 5); /* b12 b12 b02 b02 */
x5 = glmm_shuff1(x4, 3, 0, 0, 0); /* b12 b02 b02 b02 */
/* x4 = _mm_movehl_ps(r2, x4); */
x4 = wasm_i32x4_shuffle(r2, x4, 6, 7, 2, 3); /* b22 b22 b12 b12 */
x0 = glmm_fmadd(x3, x5, x0);
x1 = glmm_fmadd(x2, x4, x1);
/*
Dot Product : dest[2][2] = a02 * b20 +
a12 * b21 +
a22 * b22 +
0 * 00 */
/* x2 = _mm_movelh_ps(x8, l2); */
/* x3 = _mm_movelh_ps(x9, r2); */
x2 = wasm_i32x4_shuffle(x8, l2, 0, 1, 4, 5); /* 0.f a22 a12 a02 */
x3 = wasm_i32x4_shuffle(x9, r2, 0, 1, 4, 5); /* 0.f b22 b21 b20 */
x2 = glmm_vdots(x2, x3);
/* _mm_storeu_ps(&dest[0][0], x0); */
wasm_v128_store(&dest[0][0], x0);
/* _mm_storeu_ps(&dest[1][1], x1); */
wasm_v128_store(&dest[1][1], x1);
/* _mm_store_ss (&dest[2][2], x2); */
wasm_v128_store32_lane(&dest[2][2], x2, 0);
}
#endif
#endif /* cglm_mat3_wasm_h */

View File

@@ -0,0 +1,454 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#ifndef cglm_mat_wasm_h
#define cglm_mat_wasm_h
#if defined(__wasm__) && defined(__wasm_simd128__)
#include "../../common.h"
#include "../intrin.h"
#define glm_mat4_inv_precise_wasm(mat, dest) glm_mat4_inv_wasm(mat, dest)
CGLM_INLINE
void
glm_mat4_scale_wasm(mat4 m, float s) {
glmm_128 x0;
x0 = wasm_f32x4_splat(s);
glmm_store(m[0], wasm_f32x4_mul(glmm_load(m[0]), x0));
glmm_store(m[1], wasm_f32x4_mul(glmm_load(m[1]), x0));
glmm_store(m[2], wasm_f32x4_mul(glmm_load(m[2]), x0));
glmm_store(m[3], wasm_f32x4_mul(glmm_load(m[3]), x0));
}
CGLM_INLINE
void
glm_mat4_transp_wasm(mat4 m, mat4 dest) {
glmm_128 r0, r1, r2, r3, tmp0, tmp1, tmp2, tmp3;
r0 = glmm_load(m[0]);
r1 = glmm_load(m[1]);
r2 = glmm_load(m[2]);
r3 = glmm_load(m[3]);
/* _MM_TRANSPOSE4_PS(r0, r1, r2, r3); */
tmp0 = wasm_i32x4_shuffle(r0, r1, 0, 4, 1, 5);
tmp1 = wasm_i32x4_shuffle(r0, r1, 2, 6, 3, 7);
tmp2 = wasm_i32x4_shuffle(r2, r3, 0, 4, 1, 5);
tmp3 = wasm_i32x4_shuffle(r2, r3, 2, 6, 3, 7);
/* r0 = _mm_movelh_ps(tmp0, tmp2); */
r0 = wasm_i32x4_shuffle(tmp0, tmp2, 0, 1, 4, 5);
/* r1 = _mm_movehl_ps(tmp2, tmp0); */
r1 = wasm_i32x4_shuffle(tmp2, tmp0, 6, 7, 2, 3);
/* r2 = _mm_movelh_ps(tmp1, tmp3); */
r2 = wasm_i32x4_shuffle(tmp1, tmp3, 0, 1, 4, 5);
/* r3 = _mm_movehl_ps(tmp3, tmp1); */
r3 = wasm_i32x4_shuffle(tmp3, tmp1, 6, 7, 2, 3);
glmm_store(dest[0], r0);
glmm_store(dest[1], r1);
glmm_store(dest[2], r2);
glmm_store(dest[3], r3);
}
CGLM_INLINE
void
glm_mat4_mul_wasm(mat4 m1, mat4 m2, mat4 dest) {
/* D = R * L (Column-Major) */
glmm_128 l, r0, r1, r2, r3, v0, v1, v2, v3;
l = glmm_load(m1[0]);
r0 = glmm_load(m2[0]);
r1 = glmm_load(m2[1]);
r2 = glmm_load(m2[2]);
r3 = glmm_load(m2[3]);
v0 = wasm_f32x4_mul(glmm_splat_x(r0), l);
v1 = wasm_f32x4_mul(glmm_splat_x(r1), l);
v2 = wasm_f32x4_mul(glmm_splat_x(r2), l);
v3 = wasm_f32x4_mul(glmm_splat_x(r3), l);
l = glmm_load(m1[1]);
v0 = glmm_fmadd(glmm_splat_y(r0), l, v0);
v1 = glmm_fmadd(glmm_splat_y(r1), l, v1);
v2 = glmm_fmadd(glmm_splat_y(r2), l, v2);
v3 = glmm_fmadd(glmm_splat_y(r3), l, v3);
l = glmm_load(m1[2]);
v0 = glmm_fmadd(glmm_splat_z(r0), l, v0);
v1 = glmm_fmadd(glmm_splat_z(r1), l, v1);
v2 = glmm_fmadd(glmm_splat_z(r2), l, v2);
v3 = glmm_fmadd(glmm_splat_z(r3), l, v3);
l = glmm_load(m1[3]);
v0 = glmm_fmadd(glmm_splat_w(r0), l, v0);
v1 = glmm_fmadd(glmm_splat_w(r1), l, v1);
v2 = glmm_fmadd(glmm_splat_w(r2), l, v2);
v3 = glmm_fmadd(glmm_splat_w(r3), l, v3);
glmm_store(dest[0], v0);
glmm_store(dest[1], v1);
glmm_store(dest[2], v2);
glmm_store(dest[3], v3);
}
CGLM_INLINE
void
glm_mat4_mulv_wasm(mat4 m, vec4 v, vec4 dest) {
glmm_128 x0, x1, m0, m1, m2, m3, v0, v1, v2, v3;
m0 = glmm_load(m[0]);
m1 = glmm_load(m[1]);
m2 = glmm_load(m[2]);
m3 = glmm_load(m[3]);
x0 = glmm_load(v);
v0 = glmm_splat_x(x0);
v1 = glmm_splat_y(x0);
v2 = glmm_splat_z(x0);
v3 = glmm_splat_w(x0);
x1 = wasm_f32x4_mul(m3, v3);
x1 = glmm_fmadd(m2, v2, x1);
x1 = glmm_fmadd(m1, v1, x1);
x1 = glmm_fmadd(m0, v0, x1);
glmm_store(dest, x1);
}
CGLM_INLINE
float
glm_mat4_det_wasm(mat4 mat) {
glmm_128 r0, r1, r2, r3, x0, x1, x2;
/* 127 <- 0, [square] det(A) = det(At) */
r0 = glmm_load(mat[0]); /* d c b a */
r1 = glmm_load(mat[1]); /* h g f e */
r2 = glmm_load(mat[2]); /* l k j i */
r3 = glmm_load(mat[3]); /* p o n m */
/*
t[1] = j * p - n * l;
t[2] = j * o - n * k;
t[3] = i * p - m * l;
t[4] = i * o - m * k;
*/
x0 = glmm_fnmadd(glmm_shuff1(r3, 0, 0, 1, 1), glmm_shuff1(r2, 2, 3, 2, 3),
wasm_f32x4_mul(glmm_shuff1(r2, 0, 0, 1, 1),
glmm_shuff1(r3, 2, 3, 2, 3)));
/*
t[0] = k * p - o * l;
t[0] = k * p - o * l;
t[5] = i * n - m * j;
t[5] = i * n - m * j;
*/
x1 = glmm_fnmadd(glmm_shuff1(r3, 0, 0, 2, 2), glmm_shuff1(r2, 1, 1, 3, 3),
wasm_f32x4_mul(glmm_shuff1(r2, 0, 0, 2, 2),
glmm_shuff1(r3, 1, 1, 3, 3)));
/*
a * (f * t[0] - g * t[1] + h * t[2])
- b * (e * t[0] - g * t[3] + h * t[4])
+ c * (e * t[1] - f * t[3] + h * t[5])
- d * (e * t[2] - f * t[4] + g * t[5])
*/
x2 = glmm_fnmadd(glmm_shuff1(r1, 1, 1, 2, 2), glmm_shuff1(x0, 3, 2, 2, 0),
wasm_f32x4_mul(glmm_shuff1(r1, 0, 0, 0, 1),
wasm_i32x4_shuffle(x1, x0, 0, 0, 4, 5)));
x2 = glmm_fmadd(glmm_shuff1(r1, 2, 3, 3, 3),
wasm_i32x4_shuffle(x0, x1, 1, 3, 6, 6),
x2);
/* x2 = wasm_v128_xor(x2, wasm_f32x4_const(0.f, -0.f, 0.f, -0.f)); */
x2 = wasm_v128_xor(x2, glmm_float32x4_SIGNMASK_PNPN);
return glmm_hadd(wasm_f32x4_mul(x2, r0));
}
CGLM_INLINE
void
glm_mat4_inv_fast_wasm(mat4 mat, mat4 dest) {
glmm_128 r0, r1, r2, r3,
v0, v1, v2, v3,
t0, t1, t2, t3, t4, t5,
x0, x1, x2, x3, x4, x5, x6, x7, x8, x9;
/* x8 = wasm_f32x4_const(0.f, -0.f, 0.f, -0.f); */
x8 = glmm_float32x4_SIGNMASK_PNPN;
x9 = glmm_shuff1(x8, 2, 1, 2, 1);
/* 127 <- 0 */
r0 = glmm_load(mat[0]); /* d c b a */
r1 = glmm_load(mat[1]); /* h g f e */
r2 = glmm_load(mat[2]); /* l k j i */
r3 = glmm_load(mat[3]); /* p o n m */
/* x0 = _mm_movehl_ps(r3, r2); */
x0 = wasm_i32x4_shuffle(r3, r2, 6, 7, 2, 3); /* p o l k */
/* x3 = _mm_movelh_ps(r2, r3); */
x3 = wasm_i32x4_shuffle(r2, r3, 0, 1, 4, 5); /* n m j i */
x1 = glmm_shuff1(x0, 1, 3, 3 ,3); /* l p p p */
x2 = glmm_shuff1(x0, 0, 2, 2, 2); /* k o o o */
x4 = glmm_shuff1(x3, 1, 3, 3, 3); /* j n n n */
x7 = glmm_shuff1(x3, 0, 2, 2, 2); /* i m m m */
x6 = wasm_i32x4_shuffle(r2, r1, 0, 0, 4, 4); /* e e i i */
x5 = wasm_i32x4_shuffle(r2, r1, 1, 1, 5, 5); /* f f j j */
x3 = wasm_i32x4_shuffle(r2, r1, 2, 2, 6, 6); /* g g k k */
x0 = wasm_i32x4_shuffle(r2, r1, 3, 3, 7, 7); /* h h l l */
t0 = wasm_f32x4_mul(x3, x1);
t1 = wasm_f32x4_mul(x5, x1);
t2 = wasm_f32x4_mul(x5, x2);
t3 = wasm_f32x4_mul(x6, x1);
t4 = wasm_f32x4_mul(x6, x2);
t5 = wasm_f32x4_mul(x6, x4);
/* t1[0] = k * p - o * l;
t1[0] = k * p - o * l;
t2[0] = g * p - o * h;
t3[0] = g * l - k * h; */
t0 = glmm_fnmadd(x2, x0, t0);
/* t1[1] = j * p - n * l;
t1[1] = j * p - n * l;
t2[1] = f * p - n * h;
t3[1] = f * l - j * h; */
t1 = glmm_fnmadd(x4, x0, t1);
/* t1[2] = j * o - n * k
t1[2] = j * o - n * k;
t2[2] = f * o - n * g;
t3[2] = f * k - j * g; */
t2 = glmm_fnmadd(x4, x3, t2);
/* t1[3] = i * p - m * l;
t1[3] = i * p - m * l;
t2[3] = e * p - m * h;
t3[3] = e * l - i * h; */
t3 = glmm_fnmadd(x7, x0, t3);
/* t1[4] = i * o - m * k;
t1[4] = i * o - m * k;
t2[4] = e * o - m * g;
t3[4] = e * k - i * g; */
t4 = glmm_fnmadd(x7, x3, t4);
/* t1[5] = i * n - m * j;
t1[5] = i * n - m * j;
t2[5] = e * n - m * f;
t3[5] = e * j - i * f; */
t5 = glmm_fnmadd(x7, x5, t5);
/* x4 = _mm_movelh_ps(r0, r1); */
x4 = wasm_i32x4_shuffle(r0, r1, 0, 1, 4, 5); /* f e b a */
/* x5 = _mm_movehl_ps(r1, r0); */
x5 = wasm_i32x4_shuffle(r1, r0, 6, 7, 2, 3); /* h g d c */
x0 = glmm_shuff1(x4, 0, 0, 0, 2); /* a a a e */
x1 = glmm_shuff1(x4, 1, 1, 1, 3); /* b b b f */
x2 = glmm_shuff1(x5, 0, 0, 0, 2); /* c c c g */
x3 = glmm_shuff1(x5, 1, 1, 1, 3); /* d d d h */
v2 = wasm_f32x4_mul(x0, t1);
v1 = wasm_f32x4_mul(x0, t0);
v3 = wasm_f32x4_mul(x0, t2);
v0 = wasm_f32x4_mul(x1, t0);
v2 = glmm_fnmadd(x1, t3, v2);
v3 = glmm_fnmadd(x1, t4, v3);
v0 = glmm_fnmadd(x2, t1, v0);
v1 = glmm_fnmadd(x2, t3, v1);
v3 = glmm_fmadd(x2, t5, v3);
v0 = glmm_fmadd(x3, t2, v0);
v2 = glmm_fmadd(x3, t5, v2);
v1 = glmm_fmadd(x3, t4, v1);
/*
dest[0][0] = f * t1[0] - g * t1[1] + h * t1[2];
dest[0][1] =-(b * t1[0] - c * t1[1] + d * t1[2]);
dest[0][2] = b * t2[0] - c * t2[1] + d * t2[2];
dest[0][3] =-(b * t3[0] - c * t3[1] + d * t3[2]); */
v0 = wasm_v128_xor(v0, x8);
/*
dest[2][0] = e * t1[1] - f * t1[3] + h * t1[5];
dest[2][1] =-(a * t1[1] - b * t1[3] + d * t1[5]);
dest[2][2] = a * t2[1] - b * t2[3] + d * t2[5];
dest[2][3] =-(a * t3[1] - b * t3[3] + d * t3[5]);*/
v2 = wasm_v128_xor(v2, x8);
/*
dest[1][0] =-(e * t1[0] - g * t1[3] + h * t1[4]);
dest[1][1] = a * t1[0] - c * t1[3] + d * t1[4];
dest[1][2] =-(a * t2[0] - c * t2[3] + d * t2[4]);
dest[1][3] = a * t3[0] - c * t3[3] + d * t3[4]; */
v1 = wasm_v128_xor(v1, x9);
/*
dest[3][0] =-(e * t1[2] - f * t1[4] + g * t1[5]);
dest[3][1] = a * t1[2] - b * t1[4] + c * t1[5];
dest[3][2] =-(a * t2[2] - b * t2[4] + c * t2[5]);
dest[3][3] = a * t3[2] - b * t3[4] + c * t3[5]; */
v3 = wasm_v128_xor(v3, x9);
/* determinant */
x0 = wasm_i32x4_shuffle(v0, v1, 0, 0, 4, 4);
x1 = wasm_i32x4_shuffle(v2, v3, 0, 0, 4, 4);
x0 = wasm_i32x4_shuffle(x0, x1, 0, 2, 4, 6);
/* x0 = _mm_rcp_ps(glmm_vhadd(wasm_f32x4_mul(x0, r0))); */
x0 = wasm_f32x4_div(wasm_f32x4_const_splat(1.0f),
glmm_vhadd(wasm_f32x4_mul(x0, r0)));
glmm_store(dest[0], wasm_f32x4_mul(v0, x0));
glmm_store(dest[1], wasm_f32x4_mul(v1, x0));
glmm_store(dest[2], wasm_f32x4_mul(v2, x0));
glmm_store(dest[3], wasm_f32x4_mul(v3, x0));
}
CGLM_INLINE
void
glm_mat4_inv_wasm(mat4 mat, mat4 dest) {
glmm_128 r0, r1, r2, r3,
v0, v1, v2, v3,
t0, t1, t2, t3, t4, t5,
x0, x1, x2, x3, x4, x5, x6, x7, x8, x9;
/* x8 = wasm_f32x4_const(0.f, -0.f, 0.f, -0.f); */
x8 = glmm_float32x4_SIGNMASK_PNPN;
x9 = glmm_shuff1(x8, 2, 1, 2, 1);
/* 127 <- 0 */
r0 = glmm_load(mat[0]); /* d c b a */
r1 = glmm_load(mat[1]); /* h g f e */
r2 = glmm_load(mat[2]); /* l k j i */
r3 = glmm_load(mat[3]); /* p o n m */
/* x0 = _mm_movehl_ps(r3, r2); */
x0 = wasm_i32x4_shuffle(r3, r2, 6, 7, 2, 3); /* p o l k */
/* x3 = _mm_movelh_ps(r2, r3); */
x3 = wasm_i32x4_shuffle(r2, r3, 0, 1, 4, 5); /* n m j i */
x1 = glmm_shuff1(x0, 1, 3, 3 ,3); /* l p p p */
x2 = glmm_shuff1(x0, 0, 2, 2, 2); /* k o o o */
x4 = glmm_shuff1(x3, 1, 3, 3, 3); /* j n n n */
x7 = glmm_shuff1(x3, 0, 2, 2, 2); /* i m m m */
x6 = wasm_i32x4_shuffle(r2, r1, 0, 0, 4, 4); /* e e i i */
x5 = wasm_i32x4_shuffle(r2, r1, 1, 1, 5, 5); /* f f j j */
x3 = wasm_i32x4_shuffle(r2, r1, 2, 2, 6, 6); /* g g k k */
x0 = wasm_i32x4_shuffle(r2, r1, 3, 3, 7, 7); /* h h l l */
t0 = wasm_f32x4_mul(x3, x1);
t1 = wasm_f32x4_mul(x5, x1);
t2 = wasm_f32x4_mul(x5, x2);
t3 = wasm_f32x4_mul(x6, x1);
t4 = wasm_f32x4_mul(x6, x2);
t5 = wasm_f32x4_mul(x6, x4);
/* t1[0] = k * p - o * l;
t1[0] = k * p - o * l;
t2[0] = g * p - o * h;
t3[0] = g * l - k * h; */
t0 = glmm_fnmadd(x2, x0, t0);
/* t1[1] = j * p - n * l;
t1[1] = j * p - n * l;
t2[1] = f * p - n * h;
t3[1] = f * l - j * h; */
t1 = glmm_fnmadd(x4, x0, t1);
/* t1[2] = j * o - n * k
t1[2] = j * o - n * k;
t2[2] = f * o - n * g;
t3[2] = f * k - j * g; */
t2 = glmm_fnmadd(x4, x3, t2);
/* t1[3] = i * p - m * l;
t1[3] = i * p - m * l;
t2[3] = e * p - m * h;
t3[3] = e * l - i * h; */
t3 = glmm_fnmadd(x7, x0, t3);
/* t1[4] = i * o - m * k;
t1[4] = i * o - m * k;
t2[4] = e * o - m * g;
t3[4] = e * k - i * g; */
t4 = glmm_fnmadd(x7, x3, t4);
/* t1[5] = i * n - m * j;
t1[5] = i * n - m * j;
t2[5] = e * n - m * f;
t3[5] = e * j - i * f; */
t5 = glmm_fnmadd(x7, x5, t5);
/* x4 = _mm_movelh_ps(r0, r1); */
x4 = wasm_i32x4_shuffle(r0, r1, 0, 1, 4, 5); /* f e b a */
/* x5 = _mm_movehl_ps(r1, r0); */
x5 = wasm_i32x4_shuffle(r1, r0, 6, 7, 2, 3); /* h g d c */
x0 = glmm_shuff1(x4, 0, 0, 0, 2); /* a a a e */
x1 = glmm_shuff1(x4, 1, 1, 1, 3); /* b b b f */
x2 = glmm_shuff1(x5, 0, 0, 0, 2); /* c c c g */
x3 = glmm_shuff1(x5, 1, 1, 1, 3); /* d d d h */
v2 = wasm_f32x4_mul(x0, t1);
v1 = wasm_f32x4_mul(x0, t0);
v3 = wasm_f32x4_mul(x0, t2);
v0 = wasm_f32x4_mul(x1, t0);
v2 = glmm_fnmadd(x1, t3, v2);
v3 = glmm_fnmadd(x1, t4, v3);
v0 = glmm_fnmadd(x2, t1, v0);
v1 = glmm_fnmadd(x2, t3, v1);
v3 = glmm_fmadd(x2, t5, v3);
v0 = glmm_fmadd(x3, t2, v0);
v2 = glmm_fmadd(x3, t5, v2);
v1 = glmm_fmadd(x3, t4, v1);
/*
dest[0][0] = f * t1[0] - g * t1[1] + h * t1[2];
dest[0][1] =-(b * t1[0] - c * t1[1] + d * t1[2]);
dest[0][2] = b * t2[0] - c * t2[1] + d * t2[2];
dest[0][3] =-(b * t3[0] - c * t3[1] + d * t3[2]); */
v0 = wasm_v128_xor(v0, x8);
/*
dest[2][0] = e * t1[1] - f * t1[3] + h * t1[5];
dest[2][1] =-(a * t1[1] - b * t1[3] + d * t1[5]);
dest[2][2] = a * t2[1] - b * t2[3] + d * t2[5];
dest[2][3] =-(a * t3[1] - b * t3[3] + d * t3[5]);*/
v2 = wasm_v128_xor(v2, x8);
/*
dest[1][0] =-(e * t1[0] - g * t1[3] + h * t1[4]);
dest[1][1] = a * t1[0] - c * t1[3] + d * t1[4];
dest[1][2] =-(a * t2[0] - c * t2[3] + d * t2[4]);
dest[1][3] = a * t3[0] - c * t3[3] + d * t3[4]; */
v1 = wasm_v128_xor(v1, x9);
/*
dest[3][0] =-(e * t1[2] - f * t1[4] + g * t1[5]);
dest[3][1] = a * t1[2] - b * t1[4] + c * t1[5];
dest[3][2] =-(a * t2[2] - b * t2[4] + c * t2[5]);
dest[3][3] = a * t3[2] - b * t3[4] + c * t3[5]; */
v3 = wasm_v128_xor(v3, x9);
/* determinant */
x0 = wasm_i32x4_shuffle(v0, v1, 0, 0, 4, 4);
x1 = wasm_i32x4_shuffle(v2, v3, 0, 0, 4, 4);
x0 = wasm_i32x4_shuffle(x0, x1, 0, 2, 4, 6);
x0 = wasm_f32x4_div(wasm_f32x4_splat(1.0f), glmm_vhadd(wasm_f32x4_mul(x0, r0)));
glmm_store(dest[0], wasm_f32x4_mul(v0, x0));
glmm_store(dest[1], wasm_f32x4_mul(v1, x0));
glmm_store(dest[2], wasm_f32x4_mul(v2, x0));
glmm_store(dest[3], wasm_f32x4_mul(v3, x0));
}
#endif
#endif /* cglm_mat_wasm_h */

View File

@@ -0,0 +1,55 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#ifndef cglm_quat_wasm_h
#define cglm_quat_wasm_h
#if defined(__wasm__) && defined(__wasm_simd128__)
#include "../../common.h"
#include "../intrin.h"
CGLM_INLINE
void
glm_quat_mul_wasm(versor p, versor q, versor dest) {
/*
+ (a1 b2 + b1 a2 + c1 d2 d1 c2)i
+ (a1 c2 b1 d2 + c1 a2 + d1 b2)j
+ (a1 d2 + b1 c2 c1 b2 + d1 a2)k
a1 a2 b1 b2 c1 c2 d1 d2
*/
glmm_128 xp, xq, x1, x2, x3, r, x, y, z;
xp = glmm_load(p); /* 3 2 1 0 */
xq = glmm_load(q);
/* x1 = wasm_f32x4_const(0.f, -0.f, 0.f, -0.f); */
x1 = glmm_float32x4_SIGNMASK_PNPN; /* TODO: _mm_set1_ss() + shuff ? */
r = wasm_f32x4_mul(glmm_splat_w(xp), xq);
/* x2 = _mm_unpackhi_ps(x1, x1); */
x2 = wasm_i32x4_shuffle(x1, x1, 2, 6, 3, 7);
x3 = glmm_shuff1(x1, 3, 2, 0, 1);
x = glmm_splat_x(xp);
y = glmm_splat_y(xp);
z = glmm_splat_z(xp);
x = wasm_v128_xor(x, x1);
y = wasm_v128_xor(y, x2);
z = wasm_v128_xor(z, x3);
x1 = glmm_shuff1(xq, 0, 1, 2, 3);
x2 = glmm_shuff1(xq, 1, 0, 3, 2);
x3 = glmm_shuff1(xq, 2, 3, 0, 1);
r = glmm_fmadd(x, x1, r);
r = glmm_fmadd(y, x2, r);
r = glmm_fmadd(z, x3, r);
glmm_store(dest, r);
}
#endif
#endif /* cglm_quat_wasm_h */

View File

@@ -54,10 +54,23 @@
# endif # endif
#endif #endif
#define GLMM_NEGZEROf 0x80000000 /* 0x80000000 ---> -0.0f */
#define GLMM__SIGNMASKf(X, Y, Z, W) \
_mm_castsi128_ps(_mm_set_epi32(X, Y, Z, W))
/* _mm_set_ps(X, Y, Z, W); */
#define glmm_float32x4_SIGNMASK_PNPN GLMM__SIGNMASKf(0, GLMM_NEGZEROf, 0, GLMM_NEGZEROf)
#define glmm_float32x4_SIGNMASK_NPNP GLMM__SIGNMASKf(GLMM_NEGZEROf, 0, GLMM_NEGZEROf, 0)
#define glmm_float32x4_SIGNMASK_NPPN GLMM__SIGNMASKf(GLMM_NEGZEROf, 0, 0, GLMM_NEGZEROf)
#define glmm_float32x4_SIGNMASK_NEG _mm_castsi128_ps(_mm_set1_epi32(0x80000000)) /* _mm_set1_ps(-0.0f) */
#define glmm_float32x8_SIGNMASK_NEG _mm256_castsi256_ps(_mm256_set1_epi32(GLMM_NEGZEROf))
static inline static inline
__m128 __m128
glmm_abs(__m128 x) { glmm_abs(__m128 x) {
return _mm_andnot_ps(_mm_set1_ps(-0.0f), x); return _mm_andnot_ps(glmm_float32x4_SIGNMASK_NEG, x);
} }
static inline static inline
@@ -256,7 +269,8 @@ glmm_fnmsub(__m128 a, __m128 b, __m128 c) {
#ifdef __FMA__ #ifdef __FMA__
return _mm_fnmsub_ps(a, b, c); return _mm_fnmsub_ps(a, b, c);
#else #else
return _mm_xor_ps(_mm_add_ps(_mm_mul_ps(a, b), c), _mm_set1_ps(-0.0f)); return _mm_xor_ps(_mm_add_ps(_mm_mul_ps(a, b), c),
glmm_float32x4_SIGNMASK_NEG);
#endif #endif
} }
@@ -298,7 +312,7 @@ glmm256_fnmsub(__m256 a, __m256 b, __m256 c) {
return _mm256_fmsub_ps(a, b, c); return _mm256_fmsub_ps(a, b, c);
#else #else
return _mm256_xor_ps(_mm256_sub_ps(_mm256_mul_ps(a, b), c), return _mm256_xor_ps(_mm256_sub_ps(_mm256_mul_ps(a, b), c),
_mm256_set1_ps(-0.0f)); glmm_float32x8_SIGNMASK_NEG);
#endif #endif
} }
#endif #endif

View File

@@ -31,7 +31,7 @@ glms_aabb_(transform)(vec3s box[2], mat4s m, vec3s dest[2]) {
vec3 rawBox[2]; vec3 rawBox[2];
vec3 rawDest[2]; vec3 rawDest[2];
glms_vec3_unpack(rawBox, box, 2); glms_vec3_(unpack)(rawBox, box, 2);
glm_aabb_transform(rawBox, m.raw, rawDest); glm_aabb_transform(rawBox, m.raw, rawDest);
glms_vec3_pack(dest, rawDest, 2); glms_vec3_pack(dest, rawDest, 2);
} }
@@ -53,10 +53,10 @@ glms_aabb_(merge)(vec3s box1[2], vec3s box2[2], vec3s dest[2]) {
vec3 rawBox2[2]; vec3 rawBox2[2];
vec3 rawDest[2]; vec3 rawDest[2];
glms_vec3_unpack(rawBox1, box1, 2); glms_vec3_(unpack)(rawBox1, box1, 2);
glms_vec3_unpack(rawBox2, box2, 2); glms_vec3_(unpack)(rawBox2, box2, 2);
glm_aabb_merge(rawBox1, rawBox2, rawDest); glm_aabb_merge(rawBox1, rawBox2, rawDest);
glms_vec3_pack(dest, rawDest, 2); glms_vec3_(pack)(dest, rawDest, 2);
} }
/*! /*!
@@ -77,10 +77,10 @@ glms_aabb_(crop)(vec3s box[2], vec3s cropBox[2], vec3s dest[2]) {
vec3 rawCropBox[2]; vec3 rawCropBox[2];
vec3 rawDest[2]; vec3 rawDest[2];
glms_vec3_unpack(rawBox, box, 2); glms_vec3_(unpack)(rawBox, box, 2);
glms_vec3_unpack(rawCropBox, cropBox, 2); glms_vec3_(unpack)(rawCropBox, cropBox, 2);
glm_aabb_crop(rawBox, rawCropBox, rawDest); glm_aabb_crop(rawBox, rawCropBox, rawDest);
glms_vec3_pack(dest, rawDest, 2); glms_vec3_(pack)(dest, rawDest, 2);
} }
/*! /*!
@@ -101,8 +101,8 @@ glms_aabb_(crop_until)(vec3s box[2],
vec3s cropBox[2], vec3s cropBox[2],
vec3s clampBox[2], vec3s clampBox[2],
vec3s dest[2]) { vec3s dest[2]) {
glms_aabb_crop(box, cropBox, dest); glms_aabb_(crop)(box, cropBox, dest);
glms_aabb_merge(clampBox, dest, dest); glms_aabb_(merge)(clampBox, dest, dest);
} }
/*! /*!
@@ -125,8 +125,8 @@ glms_aabb_(frustum)(vec3s box[2], vec4s planes[6]) {
vec3 rawBox[2]; vec3 rawBox[2];
vec4 rawPlanes[6]; vec4 rawPlanes[6];
glms_vec3_unpack(rawBox, box, 2); glms_vec3_(unpack)(rawBox, box, 2);
glms_vec4_unpack(rawPlanes, planes, 6); glms_vec4_(unpack)(rawPlanes, planes, 6);
return glm_aabb_frustum(rawBox, rawPlanes); return glm_aabb_frustum(rawBox, rawPlanes);
} }
@@ -138,8 +138,8 @@ glms_aabb_(frustum)(vec3s box[2], vec4s planes[6]) {
CGLM_INLINE CGLM_INLINE
void void
glms_aabb_(invalidate)(vec3s box[2]) { glms_aabb_(invalidate)(vec3s box[2]) {
box[0] = glms_vec3_broadcast(FLT_MAX); box[0] = glms_vec3_(broadcast)(FLT_MAX);
box[1] = glms_vec3_broadcast(-FLT_MAX); box[1] = glms_vec3_(broadcast)(-FLT_MAX);
} }
/*! /*!
@@ -151,7 +151,7 @@ CGLM_INLINE
bool bool
glms_aabb_(isvalid)(vec3s box[2]) { glms_aabb_(isvalid)(vec3s box[2]) {
vec3 rawBox[2]; vec3 rawBox[2];
glms_vec3_unpack(rawBox, box, 2); glms_vec3_(unpack)(rawBox, box, 2);
return glm_aabb_isvalid(rawBox); return glm_aabb_isvalid(rawBox);
} }
@@ -174,7 +174,7 @@ glms_aabb_(size)(vec3s box[2]) {
CGLM_INLINE CGLM_INLINE
float float
glms_aabb_(radius)(vec3s box[2]) { glms_aabb_(radius)(vec3s box[2]) {
return glms_aabb_size(box) * 0.5f; return glms_aabb_(size)(box) * 0.5f;
} }
/*! /*!
@@ -186,7 +186,7 @@ glms_aabb_(radius)(vec3s box[2]) {
CGLM_INLINE CGLM_INLINE
vec3s vec3s
glms_aabb_(center)(vec3s box[2]) { glms_aabb_(center)(vec3s box[2]) {
return glms_vec3_center(box[0], box[1]); return glms_vec3_(center)(box[0], box[1]);
} }
/*! /*!
@@ -201,8 +201,8 @@ glms_aabb_(aabb)(vec3s box[2], vec3s other[2]) {
vec3 rawBox[2]; vec3 rawBox[2];
vec3 rawOther[2]; vec3 rawOther[2];
glms_vec3_unpack(rawBox, box, 2); glms_vec3_(unpack)(rawBox, box, 2);
glms_vec3_unpack(rawOther, other, 2); glms_vec3_(unpack)(rawOther, other, 2);
return glm_aabb_aabb(rawBox, rawOther); return glm_aabb_aabb(rawBox, rawOther);
} }
@@ -220,7 +220,7 @@ bool
glms_aabb_(sphere)(vec3s box[2], vec4s s) { glms_aabb_(sphere)(vec3s box[2], vec4s s) {
vec3 rawBox[2]; vec3 rawBox[2];
glms_vec3_unpack(rawBox, box, 2); glms_vec3_(unpack)(rawBox, box, 2);
return glm_aabb_sphere(rawBox, s.raw); return glm_aabb_sphere(rawBox, s.raw);
} }
@@ -235,7 +235,7 @@ bool
glms_aabb_(point)(vec3s box[2], vec3s point) { glms_aabb_(point)(vec3s box[2], vec3s point) {
vec3 rawBox[2]; vec3 rawBox[2];
glms_vec3_unpack(rawBox, box, 2); glms_vec3_(unpack)(rawBox, box, 2);
return glm_aabb_point(rawBox, point.raw); return glm_aabb_point(rawBox, point.raw);
} }
@@ -251,8 +251,8 @@ glms_aabb_(contains)(vec3s box[2], vec3s other[2]) {
vec3 rawBox[2]; vec3 rawBox[2];
vec3 rawOther[2]; vec3 rawOther[2];
glms_vec3_unpack(rawBox, box, 2); glms_vec3_(unpack)(rawBox, box, 2);
glms_vec3_unpack(rawOther, other, 2); glms_vec3_(unpack)(rawOther, other, 2);
return glm_aabb_contains(rawBox, rawOther); return glm_aabb_contains(rawBox, rawOther);
} }

View File

@@ -64,7 +64,7 @@ glms_ortho_aabb_lh_no(vec3s box[2]) {
mat4s dest; mat4s dest;
vec3 rawBox[2]; vec3 rawBox[2];
glms_vec3_unpack(rawBox, box, 2); glms_vec3_(unpack)(rawBox, box, 2);
glm_ortho_aabb_lh_no(rawBox, dest.raw); glm_ortho_aabb_lh_no(rawBox, dest.raw);
return dest; return dest;
@@ -87,7 +87,7 @@ glms_ortho_aabb_p_lh_no(vec3s box[2], float padding) {
mat4s dest; mat4s dest;
vec3 rawBox[2]; vec3 rawBox[2];
glms_vec3_unpack(rawBox, box, 2); glms_vec3_(unpack)(rawBox, box, 2);
glm_ortho_aabb_p_lh_no(rawBox, padding, dest.raw); glm_ortho_aabb_p_lh_no(rawBox, padding, dest.raw);
return dest; return dest;
@@ -110,7 +110,7 @@ glms_ortho_aabb_pz_lh_no(vec3s box[2], float padding) {
mat4s dest; mat4s dest;
vec3 rawBox[2]; vec3 rawBox[2];
glms_vec3_unpack(rawBox, box, 2); glms_vec3_(unpack)(rawBox, box, 2);
glm_ortho_aabb_pz_lh_no(rawBox, padding, dest.raw); glm_ortho_aabb_pz_lh_no(rawBox, padding, dest.raw);
return dest; return dest;

View File

@@ -64,7 +64,7 @@ glms_ortho_aabb_lh_zo(vec3s box[2]) {
mat4s dest; mat4s dest;
vec3 rawBox[2]; vec3 rawBox[2];
glms_vec3_unpack(rawBox, box, 2); glms_vec3_(unpack)(rawBox, box, 2);
glm_ortho_aabb_lh_zo(rawBox, dest.raw); glm_ortho_aabb_lh_zo(rawBox, dest.raw);
return dest; return dest;
@@ -87,7 +87,7 @@ glms_ortho_aabb_p_lh_zo(vec3s box[2], float padding) {
mat4s dest; mat4s dest;
vec3 rawBox[2]; vec3 rawBox[2];
glms_vec3_unpack(rawBox, box, 2); glms_vec3_(unpack)(rawBox, box, 2);
glm_ortho_aabb_p_lh_zo(rawBox, padding, dest.raw); glm_ortho_aabb_p_lh_zo(rawBox, padding, dest.raw);
return dest; return dest;
@@ -110,7 +110,7 @@ glms_ortho_aabb_pz_lh_zo(vec3s box[2], float padding) {
mat4s dest; mat4s dest;
vec3 rawBox[2]; vec3 rawBox[2];
glms_vec3_unpack(rawBox, box, 2); glms_vec3_(unpack)(rawBox, box, 2);
glm_ortho_aabb_pz_lh_zo(rawBox, padding, dest.raw); glm_ortho_aabb_pz_lh_zo(rawBox, padding, dest.raw);
return dest; return dest;

View File

@@ -64,7 +64,7 @@ glms_ortho_aabb_rh_no(vec3s box[2]) {
mat4s dest; mat4s dest;
vec3 rawBox[2]; vec3 rawBox[2];
glms_vec3_unpack(rawBox, box, 2); glms_vec3_(unpack)(rawBox, box, 2);
glm_ortho_aabb_rh_no(rawBox, dest.raw); glm_ortho_aabb_rh_no(rawBox, dest.raw);
return dest; return dest;
@@ -87,7 +87,7 @@ glms_ortho_aabb_p_rh_no(vec3s box[2], float padding) {
mat4s dest; mat4s dest;
vec3 rawBox[2]; vec3 rawBox[2];
glms_vec3_unpack(rawBox, box, 2); glms_vec3_(unpack)(rawBox, box, 2);
glm_ortho_aabb_p_rh_no(rawBox, padding, dest.raw); glm_ortho_aabb_p_rh_no(rawBox, padding, dest.raw);
return dest; return dest;
@@ -110,7 +110,7 @@ glms_ortho_aabb_pz_rh_no(vec3s box[2], float padding) {
mat4s dest; mat4s dest;
vec3 rawBox[2]; vec3 rawBox[2];
glms_vec3_unpack(rawBox, box, 2); glms_vec3_(unpack)(rawBox, box, 2);
glm_ortho_aabb_pz_rh_no(rawBox, padding, dest.raw); glm_ortho_aabb_pz_rh_no(rawBox, padding, dest.raw);
return dest; return dest;

View File

@@ -64,7 +64,7 @@ glms_ortho_aabb_rh_zo(vec3s box[2]) {
mat4s dest; mat4s dest;
vec3 rawBox[2]; vec3 rawBox[2];
glms_vec3_unpack(rawBox, box, 2); glms_vec3_(unpack)(rawBox, box, 2);
glm_ortho_aabb_rh_zo(rawBox, dest.raw); glm_ortho_aabb_rh_zo(rawBox, dest.raw);
return dest; return dest;
@@ -87,7 +87,7 @@ glms_ortho_aabb_p_rh_zo(vec3s box[2], float padding) {
mat4s dest; mat4s dest;
vec3 rawBox[2]; vec3 rawBox[2];
glms_vec3_unpack(rawBox, box, 2); glms_vec3_(unpack)(rawBox, box, 2);
glm_ortho_aabb_p_rh_zo(rawBox, padding, dest.raw); glm_ortho_aabb_p_rh_zo(rawBox, padding, dest.raw);
return dest; return dest;
@@ -110,7 +110,7 @@ glms_ortho_aabb_pz_rh_zo(vec3s box[2], float padding) {
mat4s dest; mat4s dest;
vec3 rawBox[2]; vec3 rawBox[2];
glms_vec3_unpack(rawBox, box, 2); glms_vec3_(unpack)(rawBox, box, 2);
glm_ortho_aabb_pz_rh_zo(rawBox, padding, dest.raw); glm_ortho_aabb_pz_rh_zo(rawBox, padding, dest.raw);
return dest; return dest;

View File

@@ -57,7 +57,7 @@ void
glms_frustum_planes(mat4s m, vec4s dest[6]) { glms_frustum_planes(mat4s m, vec4s dest[6]) {
vec4 rawDest[6]; vec4 rawDest[6];
glm_frustum_planes(m.raw, rawDest); glm_frustum_planes(m.raw, rawDest);
glms_vec4_pack(dest, rawDest, 6); glms_vec4_(pack)(dest, rawDest, 6);
} }
/*! /*!
@@ -88,7 +88,7 @@ void
glms_frustum_corners(mat4s invMat, vec4s dest[8]) { glms_frustum_corners(mat4s invMat, vec4s dest[8]) {
vec4 rawDest[8]; vec4 rawDest[8];
glm_frustum_corners(invMat.raw, rawDest); glm_frustum_corners(invMat.raw, rawDest);
glms_vec4_pack(dest, rawDest, 8); glms_vec4_(pack)(dest, rawDest, 8);
} }
/*! /*!
@@ -103,7 +103,7 @@ glms_frustum_center(vec4s corners[8]) {
vec4 rawCorners[8]; vec4 rawCorners[8];
vec4s r; vec4s r;
glms_vec4_unpack(rawCorners, corners, 8); glms_vec4_(unpack)(rawCorners, corners, 8);
glm_frustum_center(rawCorners, r.raw); glm_frustum_center(rawCorners, r.raw);
return r; return r;
} }
@@ -121,9 +121,9 @@ glms_frustum_box(vec4s corners[8], mat4s m, vec3s box[2]) {
vec4 rawCorners[8]; vec4 rawCorners[8];
vec3 rawBox[2]; vec3 rawBox[2];
glms_vec4_unpack(rawCorners, corners, 8); glms_vec4_(unpack)(rawCorners, corners, 8);
glm_frustum_box(rawCorners, m.raw, rawBox); glm_frustum_box(rawCorners, m.raw, rawBox);
glms_vec3_pack(box, rawBox, 2); glms_vec3_(pack)(box, rawBox, 2);
} }
/*! /*!
@@ -147,9 +147,9 @@ glms_frustum_corners_at(vec4s corners[8],
vec4 rawCorners[8]; vec4 rawCorners[8];
vec4 rawPlaneCorners[4]; vec4 rawPlaneCorners[4];
glms_vec4_unpack(rawCorners, corners, 8); glms_vec4_(unpack)(rawCorners, corners, 8);
glm_frustum_corners_at(rawCorners, splitDist, farDist, rawPlaneCorners); glm_frustum_corners_at(rawCorners, splitDist, farDist, rawPlaneCorners);
glms_vec4_pack(planeCorners, rawPlaneCorners, 8); glms_vec4_(pack)(planeCorners, rawPlaneCorners, 8);
} }
#endif /* cglms_frustums_h */ #endif /* cglms_frustums_h */

View File

@@ -75,7 +75,7 @@ glms_aabb_print(vec3s bbox[2],
FILE * __restrict ostream) { FILE * __restrict ostream) {
vec3 rawBbox[2]; vec3 rawBbox[2];
glms_vec3_unpack(rawBbox, bbox, 2); glms_vec3_(unpack)(rawBbox, bbox, 2);
glm_aabb_print(rawBbox, tag, ostream); glm_aabb_print(rawBbox, tag, ostream);
} }

View File

@@ -240,7 +240,7 @@ glms_mat4_(mulN)(mat4s * __restrict matrices[], uint32_t len) {
size_t i; size_t i;
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
r = glms_mat4_mul(r, *matrices[i]); r = glms_mat4_(mul)(r, *matrices[i]);
} }
return r; return r;

View File

@@ -45,7 +45,9 @@
CGLM_INLINE CGLM_INLINE
void void
glm_vec4_broadcast(float val, vec4 d) { glm_vec4_broadcast(float val, vec4 d) {
#if defined( __SSE__ ) || defined( __SSE2__ ) #if defined(__wasm__) && defined(__wasm_simd128__)
glmm_store(d, wasm_f32x4_splat(val));
#elif defined( __SSE__ ) || defined( __SSE2__ )
glmm_store(d, _mm_set1_ps(val)); glmm_store(d, _mm_set1_ps(val));
#else #else
d[0] = d[1] = d[2] = d[3] = val; d[0] = d[1] = d[2] = d[3] = val;
@@ -61,7 +63,9 @@ glm_vec4_broadcast(float val, vec4 d) {
CGLM_INLINE CGLM_INLINE
void void
glm_vec4_fill(vec4 v, float val) { glm_vec4_fill(vec4 v, float val) {
#if defined( __SSE__ ) || defined( __SSE2__ ) #if defined(__wasm__) && defined(__wasm_simd128__)
glmm_store(v, wasm_f32x4_splat(val));
#elif defined( __SSE__ ) || defined( __SSE2__ )
glmm_store(v, _mm_set1_ps(val)); glmm_store(v, _mm_set1_ps(val));
#else #else
v[0] = v[1] = v[2] = v[3] = val; v[0] = v[1] = v[2] = v[3] = val;
@@ -247,7 +251,9 @@ glm_vec4_sign(vec4 v, vec4 dest) {
CGLM_INLINE CGLM_INLINE
void void
glm_vec4_abs(vec4 v, vec4 dest) { glm_vec4_abs(vec4 v, vec4 dest) {
#if defined( __SSE__ ) || defined( __SSE2__ ) #if defined(__wasm__) && defined(__wasm_simd128__)
glmm_store(dest, glmm_abs(glmm_load(v)));
#elif defined( __SSE__ ) || defined( __SSE2__ )
glmm_store(dest, glmm_abs(glmm_load(v))); glmm_store(dest, glmm_abs(glmm_load(v)));
#elif defined(CGLM_NEON_FP) #elif defined(CGLM_NEON_FP)
vst1q_f32(dest, vabsq_f32(vld1q_f32(v))); vst1q_f32(dest, vabsq_f32(vld1q_f32(v)));
@@ -284,7 +290,9 @@ glm_vec4_fract(vec4 v, vec4 dest) {
CGLM_INLINE CGLM_INLINE
float float
glm_vec4_hadd(vec4 v) { glm_vec4_hadd(vec4 v) {
#if defined( __SSE__ ) || defined( __SSE2__ ) #if defined(__wasm__) && defined(__wasm_simd128__)
return glmm_hadd(glmm_load(v));
#elif defined( __SSE__ ) || defined( __SSE2__ )
return glmm_hadd(glmm_load(v)); return glmm_hadd(glmm_load(v));
#else #else
return v[0] + v[1] + v[2] + v[3]; return v[0] + v[1] + v[2] + v[3];
@@ -300,7 +308,9 @@ glm_vec4_hadd(vec4 v) {
CGLM_INLINE CGLM_INLINE
void void
glm_vec4_sqrt(vec4 v, vec4 dest) { glm_vec4_sqrt(vec4 v, vec4 dest) {
#if defined( __SSE__ ) || defined( __SSE2__ ) #if defined(__wasm__) && defined(__wasm_simd128__)
glmm_store(dest, wasm_f32x4_sqrt(glmm_load(v)));
#elif defined( __SSE__ ) || defined( __SSE2__ )
glmm_store(dest, _mm_sqrt_ps(glmm_load(v))); glmm_store(dest, _mm_sqrt_ps(glmm_load(v)));
#else #else
dest[0] = sqrtf(v[0]); dest[0] = sqrtf(v[0]);

View File

@@ -137,7 +137,9 @@ glm_vec4_copy3(vec4 a, vec3 dest) {
CGLM_INLINE CGLM_INLINE
void void
glm_vec4_copy(vec4 v, vec4 dest) { glm_vec4_copy(vec4 v, vec4 dest) {
#if defined( __SSE__ ) || defined( __SSE2__ ) #if defined(__wasm__) && defined(__wasm_simd128__)
glmm_store(dest, glmm_load(v));
#elif defined( __SSE__ ) || defined( __SSE2__ )
glmm_store(dest, glmm_load(v)); glmm_store(dest, glmm_load(v));
#elif defined(CGLM_NEON_FP) #elif defined(CGLM_NEON_FP)
vst1q_f32(dest, vld1q_f32(v)); vst1q_f32(dest, vld1q_f32(v));
@@ -160,10 +162,15 @@ glm_vec4_copy(vec4 v, vec4 dest) {
CGLM_INLINE CGLM_INLINE
void void
glm_vec4_ucopy(vec4 v, vec4 dest) { glm_vec4_ucopy(vec4 v, vec4 dest) {
#if defined(__wasm__) && defined(__wasm_simd128__)
/* note here wasm v128.load/v128.store support unaligned loads and stores */
wasm_v128_store(dest, wasm_v128_load(v));
#else
dest[0] = v[0]; dest[0] = v[0];
dest[1] = v[1]; dest[1] = v[1];
dest[2] = v[2]; dest[2] = v[2];
dest[3] = v[3]; dest[3] = v[3];
#endif
} }
/*! /*!
@@ -174,7 +181,9 @@ glm_vec4_ucopy(vec4 v, vec4 dest) {
CGLM_INLINE CGLM_INLINE
void void
glm_vec4_zero(vec4 v) { glm_vec4_zero(vec4 v) {
#if defined( __SSE__ ) || defined( __SSE2__ ) #if defined(__wasm__) && defined(__wasm_simd128__)
glmm_store(v, wasm_f32x4_const_splat(0.f));
#elif defined( __SSE__ ) || defined( __SSE2__ )
glmm_store(v, _mm_setzero_ps()); glmm_store(v, _mm_setzero_ps());
#elif defined(CGLM_NEON_FP) #elif defined(CGLM_NEON_FP)
vst1q_f32(v, vdupq_n_f32(0.0f)); vst1q_f32(v, vdupq_n_f32(0.0f));
@@ -194,7 +203,9 @@ glm_vec4_zero(vec4 v) {
CGLM_INLINE CGLM_INLINE
void void
glm_vec4_one(vec4 v) { glm_vec4_one(vec4 v) {
#if defined( __SSE__ ) || defined( __SSE2__ ) #if defined(__wasm__) && defined(__wasm_simd128__)
glmm_store(v, wasm_f32x4_const_splat(1.0f));
#elif defined( __SSE__ ) || defined( __SSE2__ )
glmm_store(v, _mm_set1_ps(1.0f)); glmm_store(v, _mm_set1_ps(1.0f));
#elif defined(CGLM_NEON_FP) #elif defined(CGLM_NEON_FP)
vst1q_f32(v, vdupq_n_f32(1.0f)); vst1q_f32(v, vdupq_n_f32(1.0f));
@@ -320,7 +331,9 @@ glm_vec4_norm_inf(vec4 v) {
CGLM_INLINE CGLM_INLINE
void void
glm_vec4_add(vec4 a, vec4 b, vec4 dest) { glm_vec4_add(vec4 a, vec4 b, vec4 dest) {
#if defined( __SSE__ ) || defined( __SSE2__ ) #if defined(__wasm__) && defined(__wasm_simd128__)
glmm_store(dest, wasm_f32x4_add(glmm_load(a), glmm_load(b)));
#elif defined( __SSE__ ) || defined( __SSE2__ )
glmm_store(dest, _mm_add_ps(glmm_load(a), glmm_load(b))); glmm_store(dest, _mm_add_ps(glmm_load(a), glmm_load(b)));
#elif defined(CGLM_NEON_FP) #elif defined(CGLM_NEON_FP)
vst1q_f32(dest, vaddq_f32(vld1q_f32(a), vld1q_f32(b))); vst1q_f32(dest, vaddq_f32(vld1q_f32(a), vld1q_f32(b)));
@@ -342,7 +355,9 @@ glm_vec4_add(vec4 a, vec4 b, vec4 dest) {
CGLM_INLINE CGLM_INLINE
void void
glm_vec4_adds(vec4 v, float s, vec4 dest) { glm_vec4_adds(vec4 v, float s, vec4 dest) {
#if defined( __SSE__ ) || defined( __SSE2__ ) #if defined(__wasm__) && defined(__wasm_simd128__)
glmm_store(dest, wasm_f32x4_add(glmm_load(v), wasm_f32x4_splat(s)));
#elif defined( __SSE__ ) || defined( __SSE2__ )
glmm_store(dest, _mm_add_ps(glmm_load(v), _mm_set1_ps(s))); glmm_store(dest, _mm_add_ps(glmm_load(v), _mm_set1_ps(s)));
#elif defined(CGLM_NEON_FP) #elif defined(CGLM_NEON_FP)
vst1q_f32(dest, vaddq_f32(vld1q_f32(v), vdupq_n_f32(s))); vst1q_f32(dest, vaddq_f32(vld1q_f32(v), vdupq_n_f32(s)));
@@ -364,7 +379,9 @@ glm_vec4_adds(vec4 v, float s, vec4 dest) {
CGLM_INLINE CGLM_INLINE
void void
glm_vec4_sub(vec4 a, vec4 b, vec4 dest) { glm_vec4_sub(vec4 a, vec4 b, vec4 dest) {
#if defined( __SSE__ ) || defined( __SSE2__ ) #if defined(__wasm__) && defined(__wasm_simd128__)
glmm_store(dest, wasm_f32x4_sub(glmm_load(a), glmm_load(b)));
#elif defined( __SSE__ ) || defined( __SSE2__ )
glmm_store(dest, _mm_sub_ps(glmm_load(a), glmm_load(b))); glmm_store(dest, _mm_sub_ps(glmm_load(a), glmm_load(b)));
#elif defined(CGLM_NEON_FP) #elif defined(CGLM_NEON_FP)
vst1q_f32(dest, vsubq_f32(vld1q_f32(a), vld1q_f32(b))); vst1q_f32(dest, vsubq_f32(vld1q_f32(a), vld1q_f32(b)));
@@ -386,7 +403,9 @@ glm_vec4_sub(vec4 a, vec4 b, vec4 dest) {
CGLM_INLINE CGLM_INLINE
void void
glm_vec4_subs(vec4 v, float s, vec4 dest) { glm_vec4_subs(vec4 v, float s, vec4 dest) {
#if defined( __SSE__ ) || defined( __SSE2__ ) #if defined(__wasm__) && defined(__wasm_simd128__)
glmm_store(dest, wasm_f32x4_sub(glmm_load(v), wasm_f32x4_splat(s)));
#elif defined( __SSE__ ) || defined( __SSE2__ )
glmm_store(dest, _mm_sub_ps(glmm_load(v), _mm_set1_ps(s))); glmm_store(dest, _mm_sub_ps(glmm_load(v), _mm_set1_ps(s)));
#elif defined(CGLM_NEON_FP) #elif defined(CGLM_NEON_FP)
vst1q_f32(dest, vsubq_f32(vld1q_f32(v), vdupq_n_f32(s))); vst1q_f32(dest, vsubq_f32(vld1q_f32(v), vdupq_n_f32(s)));
@@ -408,7 +427,9 @@ glm_vec4_subs(vec4 v, float s, vec4 dest) {
CGLM_INLINE CGLM_INLINE
void void
glm_vec4_mul(vec4 a, vec4 b, vec4 dest) { glm_vec4_mul(vec4 a, vec4 b, vec4 dest) {
#if defined( __SSE__ ) || defined( __SSE2__ ) #if defined(__wasm__) && defined(__wasm_simd128__)
glmm_store(dest, wasm_f32x4_mul(glmm_load(a), glmm_load(b)));
#elif defined( __SSE__ ) || defined( __SSE2__ )
glmm_store(dest, _mm_mul_ps(glmm_load(a), glmm_load(b))); glmm_store(dest, _mm_mul_ps(glmm_load(a), glmm_load(b)));
#elif defined(CGLM_NEON_FP) #elif defined(CGLM_NEON_FP)
vst1q_f32(dest, vmulq_f32(vld1q_f32(a), vld1q_f32(b))); vst1q_f32(dest, vmulq_f32(vld1q_f32(a), vld1q_f32(b)));
@@ -430,7 +451,9 @@ glm_vec4_mul(vec4 a, vec4 b, vec4 dest) {
CGLM_INLINE CGLM_INLINE
void void
glm_vec4_scale(vec4 v, float s, vec4 dest) { glm_vec4_scale(vec4 v, float s, vec4 dest) {
#if defined( __SSE__ ) || defined( __SSE2__ ) #if defined(__wasm__) && defined(__wasm_simd128__)
glmm_store(dest, wasm_f32x4_mul(glmm_load(v), wasm_f32x4_splat(s)));
#elif defined( __SSE__ ) || defined( __SSE2__ )
glmm_store(dest, _mm_mul_ps(glmm_load(v), _mm_set1_ps(s))); glmm_store(dest, _mm_mul_ps(glmm_load(v), _mm_set1_ps(s)));
#elif defined(CGLM_NEON_FP) #elif defined(CGLM_NEON_FP)
vst1q_f32(dest, vmulq_f32(vld1q_f32(v), vdupq_n_f32(s))); vst1q_f32(dest, vmulq_f32(vld1q_f32(v), vdupq_n_f32(s)));
@@ -493,7 +516,9 @@ glm_vec4_div(vec4 a, vec4 b, vec4 dest) {
CGLM_INLINE CGLM_INLINE
void void
glm_vec4_divs(vec4 v, float s, vec4 dest) { glm_vec4_divs(vec4 v, float s, vec4 dest) {
#if defined( __SSE__ ) || defined( __SSE2__ ) #if defined(__wasm__) && defined(__wasm_simd128__)
glmm_store(dest, wasm_f32x4_div(glmm_load(v), wasm_f32x4_splat(s)));
#elif defined( __SSE__ ) || defined( __SSE2__ )
glmm_store(dest, _mm_div_ps(glmm_load(v), _mm_set1_ps(s))); glmm_store(dest, _mm_div_ps(glmm_load(v), _mm_set1_ps(s)));
#else #else
glm_vec4_scale(v, 1.0f / s, dest); glm_vec4_scale(v, 1.0f / s, dest);
@@ -512,7 +537,11 @@ glm_vec4_divs(vec4 v, float s, vec4 dest) {
CGLM_INLINE CGLM_INLINE
void void
glm_vec4_addadd(vec4 a, vec4 b, vec4 dest) { glm_vec4_addadd(vec4 a, vec4 b, vec4 dest) {
#if defined( __SSE__ ) || defined( __SSE2__ ) #if defined(__wasm__) && defined(__wasm_simd128__)
glmm_store(dest, wasm_f32x4_add(
glmm_load(dest),
wasm_f32x4_add(glmm_load(a), glmm_load(b))));
#elif defined( __SSE__ ) || defined( __SSE2__ )
glmm_store(dest, _mm_add_ps(glmm_load(dest), glmm_store(dest, _mm_add_ps(glmm_load(dest),
_mm_add_ps(glmm_load(a), _mm_add_ps(glmm_load(a),
glmm_load(b)))); glmm_load(b))));
@@ -540,7 +569,11 @@ glm_vec4_addadd(vec4 a, vec4 b, vec4 dest) {
CGLM_INLINE CGLM_INLINE
void void
glm_vec4_subadd(vec4 a, vec4 b, vec4 dest) { glm_vec4_subadd(vec4 a, vec4 b, vec4 dest) {
#if defined( __SSE__ ) || defined( __SSE2__ ) #if defined(__wasm__) && defined(__wasm_simd128__)
glmm_store(dest, wasm_f32x4_add(
glmm_load(dest),
wasm_f32x4_sub(glmm_load(a), glmm_load(b))));
#elif defined( __SSE__ ) || defined( __SSE2__ )
glmm_store(dest, _mm_add_ps(glmm_load(dest), glmm_store(dest, _mm_add_ps(glmm_load(dest),
_mm_sub_ps(glmm_load(a), _mm_sub_ps(glmm_load(a),
glmm_load(b)))); glmm_load(b))));
@@ -612,7 +645,11 @@ glm_vec4_muladds(vec4 a, float s, vec4 dest) {
CGLM_INLINE CGLM_INLINE
void void
glm_vec4_maxadd(vec4 a, vec4 b, vec4 dest) { glm_vec4_maxadd(vec4 a, vec4 b, vec4 dest) {
#if defined( __SSE__ ) || defined( __SSE2__ ) #if defined(__wasm__) && defined(__wasm_simd128__)
glmm_store(dest, wasm_f32x4_add(
glmm_load(dest),
wasm_f32x4_max(glmm_load(a), glmm_load(b))));
#elif defined( __SSE__ ) || defined( __SSE2__ )
glmm_store(dest, _mm_add_ps(glmm_load(dest), glmm_store(dest, _mm_add_ps(glmm_load(dest),
_mm_max_ps(glmm_load(a), _mm_max_ps(glmm_load(a),
glmm_load(b)))); glmm_load(b))));
@@ -640,7 +677,11 @@ glm_vec4_maxadd(vec4 a, vec4 b, vec4 dest) {
CGLM_INLINE CGLM_INLINE
void void
glm_vec4_minadd(vec4 a, vec4 b, vec4 dest) { glm_vec4_minadd(vec4 a, vec4 b, vec4 dest) {
#if defined( __SSE__ ) || defined( __SSE2__ ) #if defined(__wasm__) && defined(__wasm_simd128__)
glmm_store(dest, wasm_f32x4_add(
glmm_load(dest),
wasm_f32x4_min(glmm_load(a), glmm_load(b))));
#elif defined( __SSE__ ) || defined( __SSE2__ )
glmm_store(dest, _mm_add_ps(glmm_load(dest), glmm_store(dest, _mm_add_ps(glmm_load(dest),
_mm_min_ps(glmm_load(a), _mm_min_ps(glmm_load(a),
glmm_load(b)))); glmm_load(b))));
@@ -665,8 +706,10 @@ glm_vec4_minadd(vec4 a, vec4 b, vec4 dest) {
CGLM_INLINE CGLM_INLINE
void void
glm_vec4_negate_to(vec4 v, vec4 dest) { glm_vec4_negate_to(vec4 v, vec4 dest) {
#if defined( __SSE__ ) || defined( __SSE2__ ) #if defined(__wasm__) && defined(__wasm_simd128__)
glmm_store(dest, _mm_xor_ps(glmm_load(v), _mm_set1_ps(-0.0f))); glmm_store(dest, wasm_f32x4_neg(glmm_load(v)));
#elif defined( __SSE__ ) || defined( __SSE2__ )
glmm_store(dest, _mm_xor_ps(glmm_load(v), glmm_float32x4_SIGNMASK_NEG));
#elif defined(CGLM_NEON_FP) #elif defined(CGLM_NEON_FP)
vst1q_f32(dest, vnegq_f32(vld1q_f32(v))); vst1q_f32(dest, vnegq_f32(vld1q_f32(v)));
#else #else
@@ -697,7 +740,22 @@ glm_vec4_negate(vec4 v) {
CGLM_INLINE CGLM_INLINE
void void
glm_vec4_normalize_to(vec4 v, vec4 dest) { glm_vec4_normalize_to(vec4 v, vec4 dest) {
#if defined( __SSE__ ) || defined( __SSE2__ ) #if defined(__wasm__) && defined(__wasm_simd128__)
glmm_128 xdot, x0;
float dot;
x0 = glmm_load(v);
xdot = glmm_vdot(x0, x0);
/* dot = _mm_cvtss_f32(xdot); */
dot = wasm_f32x4_extract_lane(xdot, 0);
if (dot == 0.0f) {
glmm_store(dest, wasm_f32x4_const_splat(0.f));
return;
}
glmm_store(dest, wasm_f32x4_div(x0, wasm_f32x4_sqrt(xdot)));
#elif defined( __SSE__ ) || defined( __SSE2__ )
__m128 xdot, x0; __m128 xdot, x0;
float dot; float dot;
@@ -746,7 +804,9 @@ glm_vec4_normalize(vec4 v) {
CGLM_INLINE CGLM_INLINE
float float
glm_vec4_distance(vec4 a, vec4 b) { glm_vec4_distance(vec4 a, vec4 b) {
#if defined( __SSE__ ) || defined( __SSE2__ ) #if defined(__wasm__) && defined(__wasm_simd128__)
return glmm_norm(wasm_f32x4_sub(glmm_load(a), glmm_load(b)));
#elif defined( __SSE__ ) || defined( __SSE2__ )
return glmm_norm(_mm_sub_ps(glmm_load(a), glmm_load(b))); return glmm_norm(_mm_sub_ps(glmm_load(a), glmm_load(b)));
#elif defined(CGLM_NEON_FP) #elif defined(CGLM_NEON_FP)
return glmm_norm(vsubq_f32(glmm_load(a), glmm_load(b))); return glmm_norm(vsubq_f32(glmm_load(a), glmm_load(b)));
@@ -768,7 +828,9 @@ glm_vec4_distance(vec4 a, vec4 b) {
CGLM_INLINE CGLM_INLINE
float float
glm_vec4_distance2(vec4 a, vec4 b) { glm_vec4_distance2(vec4 a, vec4 b) {
#if defined( __SSE__ ) || defined( __SSE2__ ) #if defined(__wasm__) && defined(__wasm_simd128__)
return glmm_norm2(wasm_f32x4_sub(glmm_load(a), glmm_load(b)));
#elif defined( __SSE__ ) || defined( __SSE2__ )
return glmm_norm2(_mm_sub_ps(glmm_load(a), glmm_load(b))); return glmm_norm2(_mm_sub_ps(glmm_load(a), glmm_load(b)));
#elif defined(CGLM_NEON_FP) #elif defined(CGLM_NEON_FP)
return glmm_norm2(vsubq_f32(glmm_load(a), glmm_load(b))); return glmm_norm2(vsubq_f32(glmm_load(a), glmm_load(b)));
@@ -790,7 +852,9 @@ glm_vec4_distance2(vec4 a, vec4 b) {
CGLM_INLINE CGLM_INLINE
void void
glm_vec4_maxv(vec4 a, vec4 b, vec4 dest) { glm_vec4_maxv(vec4 a, vec4 b, vec4 dest) {
#if defined( __SSE__ ) || defined( __SSE2__ ) #if defined(__wasm__) && defined(__wasm_simd128__)
glmm_store(dest, wasm_f32x4_max(glmm_load(a), glmm_load(b)));
#elif defined( __SSE__ ) || defined( __SSE2__ )
glmm_store(dest, _mm_max_ps(glmm_load(a), glmm_load(b))); glmm_store(dest, _mm_max_ps(glmm_load(a), glmm_load(b)));
#elif defined(CGLM_NEON_FP) #elif defined(CGLM_NEON_FP)
vst1q_f32(dest, vmaxq_f32(vld1q_f32(a), vld1q_f32(b))); vst1q_f32(dest, vmaxq_f32(vld1q_f32(a), vld1q_f32(b)));
@@ -812,7 +876,9 @@ glm_vec4_maxv(vec4 a, vec4 b, vec4 dest) {
CGLM_INLINE CGLM_INLINE
void void
glm_vec4_minv(vec4 a, vec4 b, vec4 dest) { glm_vec4_minv(vec4 a, vec4 b, vec4 dest) {
#if defined( __SSE__ ) || defined( __SSE2__ ) #if defined(__wasm__) && defined(__wasm_simd128__)
glmm_store(dest, wasm_f32x4_min(glmm_load(a), glmm_load(b)));
#elif defined( __SSE__ ) || defined( __SSE2__ )
glmm_store(dest, _mm_min_ps(glmm_load(a), glmm_load(b))); glmm_store(dest, _mm_min_ps(glmm_load(a), glmm_load(b)));
#elif defined(CGLM_NEON_FP) #elif defined(CGLM_NEON_FP)
vst1q_f32(dest, vminq_f32(vld1q_f32(a), vld1q_f32(b))); vst1q_f32(dest, vminq_f32(vld1q_f32(a), vld1q_f32(b)));
@@ -834,7 +900,11 @@ glm_vec4_minv(vec4 a, vec4 b, vec4 dest) {
CGLM_INLINE CGLM_INLINE
void void
glm_vec4_clamp(vec4 v, float minVal, float maxVal) { glm_vec4_clamp(vec4 v, float minVal, float maxVal) {
#if defined( __SSE__ ) || defined( __SSE2__ ) #if defined(__wasm__) && defined(__wasm_simd128__)
glmm_store(v, wasm_f32x4_min(
wasm_f32x4_max(glmm_load(v), wasm_f32x4_splat(minVal)),
wasm_f32x4_splat(maxVal)));
#elif defined( __SSE__ ) || defined( __SSE2__ )
glmm_store(v, _mm_min_ps(_mm_max_ps(glmm_load(v), _mm_set1_ps(minVal)), glmm_store(v, _mm_min_ps(_mm_max_ps(glmm_load(v), _mm_set1_ps(minVal)),
_mm_set1_ps(maxVal))); _mm_set1_ps(maxVal)));
#elif defined(CGLM_NEON_FP) #elif defined(CGLM_NEON_FP)

View File

@@ -108,11 +108,6 @@ if get_option('build_tests') == true
test_src = files( test_src = files(
'test/runner.c', 'test/runner.c',
'test/src/test_bezier.c', 'test/src/test_bezier.c',
'test/src/test_cam.c',
'test/src/test_cam_lh_no.c',
'test/src/test_cam_lh_zo.c',
'test/src/test_cam_rh_no.c',
'test/src/test_cam_rh_zo.c',
'test/src/test_clamp.c', 'test/src/test_clamp.c',
'test/src/test_common.c', 'test/src/test_common.c',
'test/src/test_euler.c', 'test/src/test_euler.c',

View File

@@ -5,11 +5,6 @@ set(TESTFILES
runner.c runner.c
src/test_euler.c src/test_euler.c
src/test_bezier.c src/test_bezier.c
src/test_cam.c
src/test_cam_lh_zo.c
src/test_cam_rh_zo.c
src/test_cam_lh_no.c
src/test_cam_rh_no.c
src/test_struct.c src/test_struct.c
src/test_clamp.c src/test_clamp.c
src/test_common.c src/test_common.c
@@ -22,6 +17,11 @@ set(TEST_RUNNER_PARAMS "")
add_executable(${TEST_MAIN} ${TESTFILES}) add_executable(${TEST_MAIN} ${TESTFILES})
target_compile_definitions(${TEST_MAIN} PRIVATE CGLM_DEFINE_PRINTS=1) target_compile_definitions(${TEST_MAIN} PRIVATE CGLM_DEFINE_PRINTS=1)
if(CMAKE_SYSTEM_NAME STREQUAL WASI)
target_compile_definitions(${TEST_MAIN} PRIVATE _WASI_EMULATED_PROCESS_CLOCKS=1)
target_link_options(${TEST_MAIN} PRIVATE "-lwasi-emulated-process-clocks")
endif()
if(NOT MSVC) if(NOT MSVC)
target_link_libraries(${TEST_MAIN} PRIVATE m) target_link_libraries(${TEST_MAIN} PRIVATE m)
endif() endif()

View File

@@ -1,55 +0,0 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#include "test_common.h"
TEST_IMPL(camera_lookat) {
mat4 view1, view2;
vec3 center,
eye = {0.024f, 14.6f, 67.04f},
dir = {0.0f, 0.0f, -1.0f},
up = {0.0f, 1.0f, 0.0f};
glm_vec3_add(eye, dir, center);
glm_lookat(eye, center, up, view1);
glm_look(eye, dir, up, view2);
ASSERTIFY(test_assert_mat4_eq(view1, view2))
TEST_SUCCESS
}
TEST_IMPL(camera_decomp) {
mat4 proj, proj2;
vec4 sizes;
float aspect, fovy, nearZ, farZ;
aspect = 0.782f;
fovy = glm_rad(49.984f);
nearZ = 0.1f;
farZ = 100.0f;
glm_perspective(fovy, aspect, nearZ, farZ, proj);
ASSERT(fabsf(aspect - glm_persp_aspect(proj)) < GLM_FLT_EPSILON)
ASSERT(fabsf(fovy - glm_persp_fovy(proj)) < GLM_FLT_EPSILON)
ASSERT(fabsf(49.984f - glm_deg(glm_persp_fovy(proj))) < GLM_FLT_EPSILON)
glm_persp_sizes(proj, fovy, sizes);
glm_frustum(-sizes[0] * 0.5f,
sizes[0] * 0.5f,
-sizes[1] * 0.5f,
sizes[1] * 0.5f,
nearZ,
farZ,
proj2);
ASSERTIFY(test_assert_mat4_eq(proj, proj2))
TEST_SUCCESS
}

View File

@@ -66,3 +66,50 @@ TEST_IMPL(GLM_PREFIX, frustum) {
TEST_SUCCESS TEST_SUCCESS
} }
TEST_IMPL(GLM_PREFIX, camera_lookat) {
mat4 view1, view2;
vec3 center,
eye = {0.024f, 14.6f, 67.04f},
dir = {0.0f, 0.0f, -1.0f},
up = {0.0f, 1.0f, 0.0f};
glm_vec3_add(eye, dir, center);
glm_lookat(eye, center, up, view1);
glm_look(eye, dir, up, view2);
ASSERTIFY(test_assert_mat4_eq(view1, view2))
TEST_SUCCESS
}
TEST_IMPL(GLM_PREFIX, camera_decomp) {
mat4 proj, proj2;
vec4 sizes;
float aspect, fovy, nearZ, farZ;
aspect = 0.782f;
fovy = glm_rad(49.984f);
nearZ = 0.1f;
farZ = 100.0f;
glm_perspective(fovy, aspect, nearZ, farZ, proj);
ASSERT(fabsf(aspect - glm_persp_aspect(proj)) < GLM_FLT_EPSILON)
ASSERT(fabsf(fovy - glm_persp_fovy(proj)) < GLM_FLT_EPSILON)
ASSERT(fabsf(49.984f - glm_deg(glm_persp_fovy(proj))) < GLM_FLT_EPSILON)
glm_persp_sizes(proj, fovy, sizes);
glm_frustum(-sizes[0] * 0.5f,
sizes[0] * 0.5f,
-sizes[1] * 0.5f,
sizes[1] * 0.5f,
nearZ,
farZ,
proj2);
ASSERTIFY(test_assert_mat4_eq(proj, proj2))
TEST_SUCCESS
}

View File

@@ -6,15 +6,17 @@
*/ */
#include "test_common.h" #include "test_common.h"
#include "../../include/cglm/clipspace/persp_lh_no.h"
#include "../../include/cglm/call/clipspace/persp_lh_no.h"
TEST_IMPL(perspective_lh_no) { TEST_IMPL(GLM_PREFIX, perspective_lh_no) {
mat4 dst; mat4 dst;
const float fovy = glm_rad(45.0f); const float fovy = glm_rad(45.0f);
const float aspect = 640/480.0f; const float aspect = 640/480.0f;
const float zNearVal = 0.1f; const float zNearVal = 0.1f;
const float zFarVal = 100.0f; const float zFarVal = 100.0f;
glm_perspective_lh_no(fovy, aspect, zNearVal, zFarVal, dst); GLM(perspective_lh_no)(fovy, aspect, zNearVal, zFarVal, dst);
/* Sanity mk. I: longhand version */ /* Sanity mk. I: longhand version */
ASSERT(test_eq(dst[0][0], 1.0f / (tanf(fovy / 2) * aspect))) ASSERT(test_eq(dst[0][0], 1.0f / (tanf(fovy / 2) * aspect)))

View File

@@ -6,15 +6,17 @@
*/ */
#include "test_common.h" #include "test_common.h"
#include "../../include/cglm/clipspace/persp_lh_zo.h"
#include "../../include/cglm/call/clipspace/persp_lh_zo.h"
TEST_IMPL(perspective_lh_zo) { TEST_IMPL(GLM_PREFIX, perspective_lh_zo) {
mat4 dst; mat4 dst;
const float fovy = glm_rad(45.0f); const float fovy = glm_rad(45.0f);
const float aspect = 640/480.0f; const float aspect = 640/480.0f;
const float zNearVal = 0.1f; const float zNearVal = 0.1f;
const float zFarVal = 100.0f; const float zFarVal = 100.0f;
glm_perspective_lh_zo(fovy, aspect, zNearVal, zFarVal, dst); GLM(perspective_lh_zo)(fovy, aspect, zNearVal, zFarVal, dst);
/* Sanity mk. I: longhand version */ /* Sanity mk. I: longhand version */
ASSERT(test_eq(dst[0][0], 1.0f / (tanf(fovy / 2) * aspect))) ASSERT(test_eq(dst[0][0], 1.0f / (tanf(fovy / 2) * aspect)))

View File

@@ -6,15 +6,17 @@
*/ */
#include "test_common.h" #include "test_common.h"
#include "../../include/cglm/clipspace/persp_rh_no.h"
#include "../../include/cglm/call/clipspace/persp_rh_no.h"
TEST_IMPL(perspective_rh_no) { TEST_IMPL(GLM_PREFIX, perspective_rh_no) {
mat4 dst; mat4 dst;
const float fovy = glm_rad(45.0f); const float fovy = glm_rad(45.0f);
const float aspect = 640/480.0f; const float aspect = 640/480.0f;
const float zNearVal = 0.1f; const float zNearVal = 0.1f;
const float zFarVal = 100.0f; const float zFarVal = 100.0f;
glm_perspective_rh_no(fovy, aspect, zNearVal, zFarVal, dst); GLM(perspective_rh_no)(fovy, aspect, zNearVal, zFarVal, dst);
/* Sanity mk. I: longhand version */ /* Sanity mk. I: longhand version */
ASSERT(test_eq(dst[0][0], 1.0f / (tanf(fovy / 2) * aspect))) ASSERT(test_eq(dst[0][0], 1.0f / (tanf(fovy / 2) * aspect)))

View File

@@ -6,15 +6,17 @@
*/ */
#include "test_common.h" #include "test_common.h"
#include "../../include/cglm/clipspace/persp_rh_zo.h"
#include "../../include/cglm/call/clipspace/persp_rh_zo.h"
TEST_IMPL(perspective_rh_zo) { TEST_IMPL(GLM_PREFIX, perspective_rh_zo) {
mat4 dst; mat4 dst;
const float fovy = glm_rad(45.0f); const float fovy = glm_rad(45.0f);
const float aspect = 640/480.0f; const float aspect = 640/480.0f;
const float zNearVal = 0.1f; const float zNearVal = 0.1f;
const float zFarVal = 100.0f; const float zFarVal = 100.0f;
glm_perspective_rh_zo(fovy, aspect, zNearVal, zFarVal, dst); GLM(perspective_rh_zo)(fovy, aspect, zNearVal, zFarVal, dst);
/* Sanity mk. I: longhand version */ /* Sanity mk. I: longhand version */
ASSERT(test_eq(dst[0][0], 1 / (tanf(fovy / 2) * aspect))) ASSERT(test_eq(dst[0][0], 1 / (tanf(fovy / 2) * aspect)))

View File

@@ -10,6 +10,10 @@
#include "../include/common.h" #include "../include/common.h"
#if !defined(_WIN32) && !defined(_MSC_VER)
# pragma GCC diagnostic ignored "-Wstrict-prototypes"
#endif
void void
test_rand_mat4(mat4 dest); test_rand_mat4(mat4 dest);

View File

@@ -28,7 +28,11 @@
#include "test_affine2d.h" #include "test_affine2d.h"
#include "test_affine_mat.h" #include "test_affine_mat.h"
#include "test_ray.h" #include "test_ray.h"
#include "test_camera.h" #include "test_cam.h"
#include "test_cam_lh_no.h"
#include "test_cam_lh_zo.h"
#include "test_cam_rh_no.h"
#include "test_cam_rh_zo.h"
#undef GLM #undef GLM
#undef GLM_PREFIX #undef GLM_PREFIX
@@ -55,7 +59,11 @@
#include "test_affine2d.h" #include "test_affine2d.h"
#include "test_affine_mat.h" #include "test_affine_mat.h"
#include "test_ray.h" #include "test_ray.h"
#include "test_camera.h" #include "test_cam.h"
#include "test_cam_lh_no.h"
#include "test_cam_lh_zo.h"
#include "test_cam_rh_no.h"
#include "test_cam_rh_zo.h"
#undef GLM #undef GLM
#undef GLM_PREFIX #undef GLM_PREFIX

View File

@@ -223,12 +223,19 @@ TEST_DECLARE(glmc_mat2_swap_row)
TEST_DECLARE(glmc_mat2_rmc) TEST_DECLARE(glmc_mat2_rmc)
/* camera (incl [LR]H cross [NZ]O) */ /* camera (incl [LR]H cross [NZ]O) */
TEST_DECLARE(perspective_lh_zo) TEST_DECLARE(glm_perspective_lh_zo)
TEST_DECLARE(perspective_rh_zo) TEST_DECLARE(glm_perspective_rh_zo)
TEST_DECLARE(perspective_lh_no) TEST_DECLARE(glm_perspective_lh_no)
TEST_DECLARE(perspective_rh_no) TEST_DECLARE(glm_perspective_rh_no)
TEST_DECLARE(camera_lookat) TEST_DECLARE(glm_camera_lookat)
TEST_DECLARE(camera_decomp) TEST_DECLARE(glm_camera_decomp)
TEST_DECLARE(glmc_perspective_lh_zo)
TEST_DECLARE(glmc_perspective_rh_zo)
TEST_DECLARE(glmc_perspective_lh_no)
TEST_DECLARE(glmc_perspective_rh_no)
TEST_DECLARE(glmc_camera_lookat)
TEST_DECLARE(glmc_camera_decomp)
TEST_DECLARE(glm_frustum) TEST_DECLARE(glm_frustum)
@@ -1057,12 +1064,19 @@ TEST_LIST {
TEST_ENTRY(glmc_mat2_rmc) TEST_ENTRY(glmc_mat2_rmc)
/* camera (incl [LR]H cross [NZ]O) */ /* camera (incl [LR]H cross [NZ]O) */
TEST_ENTRY(perspective_lh_zo) TEST_ENTRY(glm_perspective_lh_zo)
TEST_ENTRY(perspective_rh_zo) TEST_ENTRY(glm_perspective_rh_zo)
TEST_ENTRY(perspective_lh_no) TEST_ENTRY(glm_perspective_lh_no)
TEST_ENTRY(perspective_rh_no) TEST_ENTRY(glm_perspective_rh_no)
TEST_ENTRY(camera_lookat) TEST_ENTRY(glm_camera_lookat)
TEST_ENTRY(camera_decomp) TEST_ENTRY(glm_camera_decomp)
TEST_ENTRY(glmc_perspective_lh_zo)
TEST_ENTRY(glmc_perspective_rh_zo)
TEST_ENTRY(glmc_perspective_lh_no)
TEST_ENTRY(glmc_perspective_rh_no)
TEST_ENTRY(glmc_camera_lookat)
TEST_ENTRY(glmc_camera_decomp)
TEST_ENTRY(glm_frustum) TEST_ENTRY(glm_frustum)

View File

@@ -46,11 +46,6 @@
<ClCompile Include="..\test\runner.c" /> <ClCompile Include="..\test\runner.c" />
<ClCompile Include="..\test\src\tests.c" /> <ClCompile Include="..\test\src\tests.c" />
<ClCompile Include="..\test\src\test_bezier.c" /> <ClCompile Include="..\test\src\test_bezier.c" />
<ClCompile Include="..\test\src\test_cam.c" />
<ClCompile Include="..\test\src\test_cam_lh_no.c" />
<ClCompile Include="..\test\src\test_cam_lh_zo.c" />
<ClCompile Include="..\test\src\test_cam_rh_no.c" />
<ClCompile Include="..\test\src\test_cam_rh_zo.c" />
<ClCompile Include="..\test\src\test_clamp.c" /> <ClCompile Include="..\test\src\test_clamp.c" />
<ClCompile Include="..\test\src\test_common.c" /> <ClCompile Include="..\test\src\test_common.c" />
<ClCompile Include="..\test\src\test_euler.c" /> <ClCompile Include="..\test\src\test_euler.c" />
@@ -61,7 +56,11 @@
<ClInclude Include="..\test\src\test_affine.h" /> <ClInclude Include="..\test\src\test_affine.h" />
<ClInclude Include="..\test\src\test_affine2d.h" /> <ClInclude Include="..\test\src\test_affine2d.h" />
<ClInclude Include="..\test\src\test_affine_mat.h" /> <ClInclude Include="..\test\src\test_affine_mat.h" />
<ClInclude Include="..\test\src\test_camera.h" /> <ClInclude Include="..\test\src\test_cam.h" />
<ClInclude Include="..\test\src\test_cam_lh_no.h" />
<ClInclude Include="..\test\src\test_cam_lh_zo.h" />
<ClInclude Include="..\test\src\test_cam_rh_no.h" />
<ClInclude Include="..\test\src\test_cam_rh_zo.h" />
<ClInclude Include="..\test\src\test_common.h" /> <ClInclude Include="..\test\src\test_common.h" />
<ClInclude Include="..\test\src\test_ivec2.h" /> <ClInclude Include="..\test\src\test_ivec2.h" />
<ClInclude Include="..\test\src\test_ivec3.h" /> <ClInclude Include="..\test\src\test_ivec3.h" />
@@ -72,10 +71,10 @@
<ClInclude Include="..\test\src\test_plane.h" /> <ClInclude Include="..\test\src\test_plane.h" />
<ClInclude Include="..\test\src\test_project.h" /> <ClInclude Include="..\test\src\test_project.h" />
<ClInclude Include="..\test\src\test_quat.h" /> <ClInclude Include="..\test\src\test_quat.h" />
<ClInclude Include="..\test\src\test_ray.h" />
<ClInclude Include="..\test\src\test_vec2.h" /> <ClInclude Include="..\test\src\test_vec2.h" />
<ClInclude Include="..\test\src\test_vec3.h" /> <ClInclude Include="..\test\src\test_vec3.h" />
<ClInclude Include="..\test\src\test_vec4.h" /> <ClInclude Include="..\test\src\test_vec4.h" />
<ClInclude Include="..\test\src\test_ray.h" />
<ClInclude Include="..\test\tests.h" /> <ClInclude Include="..\test\tests.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -17,9 +17,6 @@
<ClCompile Include="..\test\src\test_bezier.c"> <ClCompile Include="..\test\src\test_bezier.c">
<Filter>src</Filter> <Filter>src</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\test\src\test_cam.c">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="..\test\src\test_clamp.c"> <ClCompile Include="..\test\src\test_clamp.c">
<Filter>src</Filter> <Filter>src</Filter>
</ClCompile> </ClCompile>
@@ -35,18 +32,6 @@
<ClCompile Include="..\test\src\tests.c"> <ClCompile Include="..\test\src\tests.c">
<Filter>src</Filter> <Filter>src</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\test\src\test_cam_lh_no.c">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="..\test\src\test_cam_lh_zo.c">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="..\test\src\test_cam_rh_no.c">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="..\test\src\test_cam_rh_zo.c">
<Filter>src</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\test\tests.h"> <ClInclude Include="..\test\tests.h">
@@ -58,46 +43,28 @@
<ClInclude Include="..\test\include\common.h"> <ClInclude Include="..\test\include\common.h">
<Filter>include</Filter> <Filter>include</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\test\src\test_mat3.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="..\test\src\test_mat4.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="..\test\src\test_project.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="..\test\src\test_quat.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="..\test\src\test_vec3.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="..\test\src\test_vec4.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="..\test\src\test_affine.h"> <ClInclude Include="..\test\src\test_affine.h">
<Filter>src</Filter> <Filter>src</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\test\src\test_affine_mat.h"> <ClInclude Include="..\test\src\test_affine_mat.h">
<Filter>src</Filter> <Filter>src</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\test\src\test_mat2.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="..\test\src\test_plane.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="..\test\src\test_vec2.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="..\test\src\test_ray.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="..\test\src\test_affine2d.h"> <ClInclude Include="..\test\src\test_affine2d.h">
<Filter>src</Filter> <Filter>src</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\test\src\test_camera.h"> <ClInclude Include="..\test\src\test_cam.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="..\test\src\test_cam_lh_no.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="..\test\src\test_cam_lh_zo.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="..\test\src\test_cam_rh_no.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="..\test\src\test_cam_rh_zo.h">
<Filter>src</Filter> <Filter>src</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\test\src\test_ivec2.h"> <ClInclude Include="..\test\src\test_ivec2.h">
@@ -109,5 +76,35 @@
<ClInclude Include="..\test\src\test_ivec4.h"> <ClInclude Include="..\test\src\test_ivec4.h">
<Filter>src</Filter> <Filter>src</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\test\src\test_mat2.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="..\test\src\test_mat3.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="..\test\src\test_mat4.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="..\test\src\test_plane.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="..\test\src\test_project.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="..\test\src\test_quat.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="..\test\src\test_ray.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="..\test\src\test_vec2.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="..\test\src\test_vec3.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="..\test\src\test_vec4.h">
<Filter>src</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
</Project> </Project>