From 62814deb328201ba6fe3a122514c9fbc5d61a730 Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Mon, 27 Aug 2018 08:34:01 -0700 Subject: [PATCH 01/13] Added read of map_d from MTL files --- libraries/fbx/src/OBJReader.cpp | 31 +++++++++++++++++++++---------- libraries/fbx/src/OBJReader.h | 2 ++ 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/libraries/fbx/src/OBJReader.cpp b/libraries/fbx/src/OBJReader.cpp index caac08f777..501fb72130 100644 --- a/libraries/fbx/src/OBJReader.cpp +++ b/libraries/fbx/src/OBJReader.cpp @@ -263,15 +263,19 @@ void OBJReader::parseMaterialLibrary(QIODevice* device) { default: materials[matName] = currentMaterial; #ifdef WANT_DEBUG - qCDebug(modelformat) << "OBJ Reader Last material illumination model:" << currentMaterial.illuminationModel << - " shininess:" << currentMaterial.shininess << " opacity:" << currentMaterial.opacity << - " diffuse color:" << currentMaterial.diffuseColor << " specular color:" << - currentMaterial.specularColor << " emissive color:" << currentMaterial.emissiveColor << - " diffuse texture:" << currentMaterial.diffuseTextureFilename << " specular texture:" << - currentMaterial.specularTextureFilename << " emissive texture:" << - currentMaterial.emissiveTextureFilename << " bump texture:" << - currentMaterial.bumpTextureFilename; - #endif + qCDebug(modelformat) << + "OBJ Reader Last material illumination model:" << currentMaterial.illuminationModel << + " shininess:" << currentMaterial.shininess << + " opacity:" << currentMaterial.opacity << + " diffuse color:" << currentMaterial.diffuseColor << + " specular color:" << currentMaterial.specularColor << + " emissive color:" << currentMaterial.emissiveColor << + " diffuse texture:" << currentMaterial.diffuseTextureFilename << + " specular texture:" << currentMaterial.specularTextureFilename << + " emissive texture:" << currentMaterial.emissiveTextureFilename << + " bump texture:" << currentMaterial.bumpTextureFilename; + " opacity texture:" << currentMaterial.opacityTextureFilename; +#endif return; } QByteArray token = tokenizer.getDatum(); @@ -289,6 +293,8 @@ void OBJReader::parseMaterialLibrary(QIODevice* device) { currentMaterial.emissiveTextureFilename = ""; currentMaterial.specularTextureFilename = ""; currentMaterial.bumpTextureFilename = ""; + currentMaterial.opacityTextureFilename = ""; + } else if (token == "Ns") { currentMaterial.shininess = tokenizer.getFloat(); } else if (token == "Ni") { @@ -321,7 +327,7 @@ void OBJReader::parseMaterialLibrary(QIODevice* device) { currentMaterial.emissiveColor = tokenizer.getVec3(); } else if (token == "Ks") { currentMaterial.specularColor = tokenizer.getVec3(); - } else if ((token == "map_Kd") || (token == "map_Ke") || (token == "map_Ks") || (token == "map_bump") || (token == "bump")) { + } else if ((token == "map_Kd") || (token == "map_Ke") || (token == "map_Ks") || (token == "map_bump") || (token == "bump") || (token == "map_d")) { const QByteArray textureLine = tokenizer.getLineAsDatum(); QByteArray filename; OBJMaterialTextureOptions textureOptions; @@ -341,6 +347,8 @@ void OBJReader::parseMaterialLibrary(QIODevice* device) { } else if ((token == "map_bump") || (token == "bump")) { currentMaterial.bumpTextureFilename = filename; currentMaterial.bumpTextureOptions = textureOptions; + } else if (token == "map_d") { + currentMaterial.opacityTextureFilename = filename; } } } @@ -900,6 +908,9 @@ FBXGeometry::Pointer OBJReader::readOBJ(QByteArray& model, const QVariantHash& m fbxMaterial.normalTexture.isBumpmap = true; fbxMaterial.bumpMultiplier = objMaterial.bumpTextureOptions.bumpMultiplier; } + if (!objMaterial.opacityTextureFilename.isEmpty()) { + fbxMaterial.opacityTexture.filename = objMaterial.opacityTextureFilename; + } modelMaterial->setEmissive(fbxMaterial.emissiveColor); modelMaterial->setAlbedo(fbxMaterial.diffuseColor); diff --git a/libraries/fbx/src/OBJReader.h b/libraries/fbx/src/OBJReader.h index 13ddc6e21c..e432a3ea51 100644 --- a/libraries/fbx/src/OBJReader.h +++ b/libraries/fbx/src/OBJReader.h @@ -66,6 +66,8 @@ public: QByteArray specularTextureFilename; QByteArray emissiveTextureFilename; QByteArray bumpTextureFilename; + QByteArray opacityTextureFilename; + OBJMaterialTextureOptions bumpTextureOptions; int illuminationModel; bool used { false }; From bf348f43aa55d790423f6e5a828e0372e9843f90 Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Wed, 29 Aug 2018 09:55:54 -0700 Subject: [PATCH 02/13] Prepare for runtime CPU dispatch of all SIMD functions --- libraries/audio/src/AudioHRTF.cpp | 54 ++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 19 deletions(-) diff --git a/libraries/audio/src/AudioHRTF.cpp b/libraries/audio/src/AudioHRTF.cpp index 23adcde0c5..aef4ef3326 100644 --- a/libraries/audio/src/AudioHRTF.cpp +++ b/libraries/audio/src/AudioHRTF.cpp @@ -276,23 +276,8 @@ static void FIR_1x4_SSE(float* src, float* dst0, float* dst1, float* dst2, float } } -// -// Runtime CPU dispatch -// - -#include "CPUDetect.h" - -void FIR_1x4_AVX2(float* src, float* dst0, float* dst1, float* dst2, float* dst3, float coef[4][HRTF_TAPS], int numFrames); -void FIR_1x4_AVX512(float* src, float* dst0, float* dst1, float* dst2, float* dst3, float coef[4][HRTF_TAPS], int numFrames); - -static void FIR_1x4(float* src, float* dst0, float* dst1, float* dst2, float* dst3, float coef[4][HRTF_TAPS], int numFrames) { - - static auto f = cpuSupportsAVX512() ? FIR_1x4_AVX512 : (cpuSupportsAVX2() ? FIR_1x4_AVX2 : FIR_1x4_SSE); - (*f)(src, dst0, dst1, dst2, dst3, coef, numFrames); // dispatch -} - // 4 channel planar to interleaved -static void interleave_4x4(float* src0, float* src1, float* src2, float* src3, float* dst, int numFrames) { +static void interleave_4x4_SSE(float* src0, float* src1, float* src2, float* src3, float* dst, int numFrames) { assert(numFrames % 4 == 0); @@ -323,7 +308,7 @@ static void interleave_4x4(float* src0, float* src1, float* src2, float* src3, f // process 2 cascaded biquads on 4 channels (interleaved) // biquads computed in parallel, by adding one sample of delay -static void biquad2_4x4(float* src, float* dst, float coef[5][8], float state[3][8], int numFrames) { +static void biquad2_4x4_SSE(float* src, float* dst, float coef[5][8], float state[3][8], int numFrames) { // enable flush-to-zero mode to prevent denormals unsigned int ftz = _MM_GET_FLUSH_ZERO_MODE(); @@ -388,7 +373,7 @@ static void biquad2_4x4(float* src, float* dst, float coef[5][8], float state[3] } // crossfade 4 inputs into 2 outputs with accumulation (interleaved) -static void crossfade_4x2(float* src, float* dst, const float* win, int numFrames) { +static void crossfade_4x2_SSE(float* src, float* dst, const float* win, int numFrames) { assert(numFrames % 4 == 0); @@ -435,7 +420,7 @@ static void crossfade_4x2(float* src, float* dst, const float* win, int numFrame } // linear interpolation with gain -static void interpolate(float* dst, const float* src0, const float* src1, float frac, float gain) { +static void interpolate_SSE(float* dst, const float* src0, const float* src1, float frac, float gain) { __m128 f0 = _mm_set1_ps(gain * (1.0f - frac)); __m128 f1 = _mm_set1_ps(gain * frac); @@ -453,6 +438,37 @@ static void interpolate(float* dst, const float* src0, const float* src1, float } } +// +// Runtime CPU dispatch +// + +#include "CPUDetect.h" + +void FIR_1x4_AVX2(float* src, float* dst0, float* dst1, float* dst2, float* dst3, float coef[4][HRTF_TAPS], int numFrames); +void FIR_1x4_AVX512(float* src, float* dst0, float* dst1, float* dst2, float* dst3, float coef[4][HRTF_TAPS], int numFrames); + +static void FIR_1x4(float* src, float* dst0, float* dst1, float* dst2, float* dst3, float coef[4][HRTF_TAPS], int numFrames) { + + static auto f = cpuSupportsAVX512() ? FIR_1x4_AVX512 : (cpuSupportsAVX2() ? FIR_1x4_AVX2 : FIR_1x4_SSE); + (*f)(src, dst0, dst1, dst2, dst3, coef, numFrames); // dispatch +} + +static void interleave_4x4(float* src0, float* src1, float* src2, float* src3, float* dst, int numFrames) { + interleave_4x4_SSE(src0, src1, src2, src3, dst, numFrames); +} + +static void biquad2_4x4(float* src, float* dst, float coef[5][8], float state[3][8], int numFrames) { + biquad2_4x4_SSE(src, dst, coef, state, numFrames); +} + +static void crossfade_4x2(float* src, float* dst, const float* win, int numFrames) { + crossfade_4x2_SSE(src, dst, win, numFrames); +} + +static void interpolate(float* dst, const float* src0, const float* src1, float frac, float gain) { + interpolate_SSE(dst, src0, src1, frac, gain); +} + #else // portable reference code // 1 channel input, 4 channel output From 6f151ad2837cb252dd8ea16c5baa3e415ca23363 Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Wed, 29 Aug 2018 10:03:40 -0700 Subject: [PATCH 03/13] Consistent parameter order for SIMD functions --- libraries/audio/src/AudioHRTF.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libraries/audio/src/AudioHRTF.cpp b/libraries/audio/src/AudioHRTF.cpp index aef4ef3326..20d782a414 100644 --- a/libraries/audio/src/AudioHRTF.cpp +++ b/libraries/audio/src/AudioHRTF.cpp @@ -420,7 +420,7 @@ static void crossfade_4x2_SSE(float* src, float* dst, const float* win, int numF } // linear interpolation with gain -static void interpolate_SSE(float* dst, const float* src0, const float* src1, float frac, float gain) { +static void interpolate_SSE(const float* src0, const float* src1, float* dst, float frac, float gain) { __m128 f0 = _mm_set1_ps(gain * (1.0f - frac)); __m128 f1 = _mm_set1_ps(gain * frac); @@ -465,8 +465,8 @@ static void crossfade_4x2(float* src, float* dst, const float* win, int numFrame crossfade_4x2_SSE(src, dst, win, numFrames); } -static void interpolate(float* dst, const float* src0, const float* src1, float frac, float gain) { - interpolate_SSE(dst, src0, src1, frac, gain); +static void interpolate(const float* src0, const float* src1, float* dst, float frac, float gain) { + interpolate_SSE(src0, src1, dst, frac, gain); } #else // portable reference code @@ -731,7 +731,7 @@ static void crossfade_4x2(float* src, float* dst, const float* win, int numFrame } // linear interpolation with gain -static void interpolate(float* dst, const float* src0, const float* src1, float frac, float gain) { +static void interpolate(const float* src0, const float* src1, float* dst, float frac, float gain) { float f0 = gain * (1.0f - frac); float f1 = gain * frac; @@ -983,8 +983,8 @@ static void setFilters(float firCoef[4][HRTF_TAPS], float bqCoef[5][8], int dela azimuthToIndex(azimuth, az0, az1, frac); // interpolate FIR - interpolate(firCoef[channel+0], ir_table_table[index][azL0][0], ir_table_table[index][azL1][0], fracL, gain * gainL); - interpolate(firCoef[channel+1], ir_table_table[index][azR0][1], ir_table_table[index][azR1][1], fracR, gain * gainR); + interpolate(ir_table_table[index][azL0][0], ir_table_table[index][azL1][0], firCoef[channel+0], fracL, gain * gainL); + interpolate(ir_table_table[index][azR0][1], ir_table_table[index][azR1][1], firCoef[channel+1], fracR, gain * gainR); // interpolate ITD float itd = (1.0f - frac) * itd_table_table[index][az0] + frac * itd_table_table[index][az1]; From 3e17556cc1c14c7263d8f27cf440476c7be22451 Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Wed, 29 Aug 2018 10:47:02 -0700 Subject: [PATCH 04/13] Prefer static_assert() over assert() --- libraries/audio/src/AudioHRTF.cpp | 6 +++--- libraries/audio/src/avx2/AudioHRTF_avx2.cpp | 2 +- libraries/audio/src/avx512/AudioHRTF_avx512.cpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libraries/audio/src/AudioHRTF.cpp b/libraries/audio/src/AudioHRTF.cpp index 20d782a414..7895a70595 100644 --- a/libraries/audio/src/AudioHRTF.cpp +++ b/libraries/audio/src/AudioHRTF.cpp @@ -240,7 +240,7 @@ static void FIR_1x4_SSE(float* src, float* dst0, float* dst1, float* dst2, float float* ps = &src[i - HRTF_TAPS + 1]; // process forwards - assert(HRTF_TAPS % 4 == 0); + static_assert(HRTF_TAPS % 4 == 0, "HRTF_TAPS must be a multiple of 4"); for (int k = 0; k < HRTF_TAPS; k += 4) { @@ -425,7 +425,7 @@ static void interpolate_SSE(const float* src0, const float* src1, float* dst, fl __m128 f0 = _mm_set1_ps(gain * (1.0f - frac)); __m128 f1 = _mm_set1_ps(gain * frac); - assert(HRTF_TAPS % 4 == 0); + static_assert(HRTF_TAPS % 4 == 0, "HRTF_TAPS must be a multiple of 4"); for (int k = 0; k < HRTF_TAPS; k += 4) { @@ -505,7 +505,7 @@ static void FIR_1x4(float* src, float* dst0, float* dst1, float* dst2, float* ds float* ps = &src[i - HRTF_TAPS + 1]; // process forwards - assert(HRTF_TAPS % 4 == 0); + static_assert(HRTF_TAPS % 4 == 0, "HRTF_TAPS must be a multiple of 4"); for (int k = 0; k < HRTF_TAPS; k += 4) { diff --git a/libraries/audio/src/avx2/AudioHRTF_avx2.cpp b/libraries/audio/src/avx2/AudioHRTF_avx2.cpp index e89128b173..501f010236 100644 --- a/libraries/audio/src/avx2/AudioHRTF_avx2.cpp +++ b/libraries/audio/src/avx2/AudioHRTF_avx2.cpp @@ -44,7 +44,7 @@ void FIR_1x4_AVX2(float* src, float* dst0, float* dst1, float* dst2, float* dst3 float* ps = &src[i - HRTF_TAPS + 1]; // process forwards - assert(HRTF_TAPS % 4 == 0); + static_assert(HRTF_TAPS % 4 == 0, "HRTF_TAPS must be a multiple of 4"); for (int k = 0; k < HRTF_TAPS; k += 4) { diff --git a/libraries/audio/src/avx512/AudioHRTF_avx512.cpp b/libraries/audio/src/avx512/AudioHRTF_avx512.cpp index a8bb62be35..fcec81fa4c 100644 --- a/libraries/audio/src/avx512/AudioHRTF_avx512.cpp +++ b/libraries/audio/src/avx512/AudioHRTF_avx512.cpp @@ -44,7 +44,7 @@ void FIR_1x4_AVX512(float* src, float* dst0, float* dst1, float* dst2, float* ds float* ps = &src[i - HRTF_TAPS + 1]; // process forwards - assert(HRTF_TAPS % 4 == 0); + static_assert(HRTF_TAPS % 4 == 0, "HRTF_TAPS must be a multiple of 4"); for (int k = 0; k < HRTF_TAPS; k += 4) { From 6cc31e7397c8de9361f44febc3aa91278f4730d2 Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Wed, 29 Aug 2018 13:30:13 -0700 Subject: [PATCH 05/13] AVX2 implementation of biquad2_4x4() --- libraries/audio/src/AudioHRTF.cpp | 6 ++- libraries/audio/src/avx2/AudioHRTF_avx2.cpp | 45 +++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/libraries/audio/src/AudioHRTF.cpp b/libraries/audio/src/AudioHRTF.cpp index 7895a70595..0f87df2346 100644 --- a/libraries/audio/src/AudioHRTF.cpp +++ b/libraries/audio/src/AudioHRTF.cpp @@ -457,8 +457,12 @@ static void interleave_4x4(float* src0, float* src1, float* src2, float* src3, f interleave_4x4_SSE(src0, src1, src2, src3, dst, numFrames); } +void biquad2_4x4_AVX2(float* src, float* dst, float coef[5][8], float state[3][8], int numFrames); + static void biquad2_4x4(float* src, float* dst, float coef[5][8], float state[3][8], int numFrames) { - biquad2_4x4_SSE(src, dst, coef, state, numFrames); + + static auto f = cpuSupportsAVX2() ? biquad2_4x4_AVX2 : biquad2_4x4_SSE; + (*f)(src, dst, coef, state, numFrames); // dispatch } static void crossfade_4x2(float* src, float* dst, const float* win, int numFrames) { diff --git a/libraries/audio/src/avx2/AudioHRTF_avx2.cpp b/libraries/audio/src/avx2/AudioHRTF_avx2.cpp index 501f010236..0c3c6b5096 100644 --- a/libraries/audio/src/avx2/AudioHRTF_avx2.cpp +++ b/libraries/audio/src/avx2/AudioHRTF_avx2.cpp @@ -87,4 +87,49 @@ void FIR_1x4_AVX2(float* src, float* dst0, float* dst1, float* dst2, float* dst3 _mm256_zeroupper(); } +// process 2 cascaded biquads on 4 channels (interleaved) +// biquads are computed in parallel, by adding one sample of delay +void biquad2_4x4_AVX2(float* src, float* dst, float coef[5][8], float state[3][8], int numFrames) { + + // enable flush-to-zero mode to prevent denormals + unsigned int ftz = _MM_GET_FLUSH_ZERO_MODE(); + _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON); + + // restore state + __m256 x0 = _mm256_setzero_ps(); + __m256 y0 = _mm256_loadu_ps(state[0]); + __m256 w1 = _mm256_loadu_ps(state[1]); + __m256 w2 = _mm256_loadu_ps(state[2]); + + // biquad coefs + __m256 b0 = _mm256_loadu_ps(coef[0]); + __m256 b1 = _mm256_loadu_ps(coef[1]); + __m256 b2 = _mm256_loadu_ps(coef[2]); + __m256 a1 = _mm256_loadu_ps(coef[3]); + __m256 a2 = _mm256_loadu_ps(coef[4]); + + for (int i = 0; i < numFrames; i++) { + + // x0 = (first biquad output << 128) | input + x0 = _mm256_insertf128_ps(_mm256_permute2f128_ps(y0, y0, 0x01), _mm_loadu_ps(&src[4*i]), 0); + + // transposed Direct Form II + y0 = _mm256_fmadd_ps(x0, b0, w1); + w1 = _mm256_fmadd_ps(x0, b1, w2); + w2 = _mm256_mul_ps(x0, b2); + w1 = _mm256_fnmadd_ps(y0, a1, w1); + w2 = _mm256_fnmadd_ps(y0, a2, w2); + + _mm_storeu_ps(&dst[4*i], _mm256_extractf128_ps(y0, 1)); // second biquad output + } + + // save state + _mm256_storeu_ps(state[0], y0); + _mm256_storeu_ps(state[1], w1); + _mm256_storeu_ps(state[2], w2); + + _MM_SET_FLUSH_ZERO_MODE(ftz); + _mm256_zeroupper(); +} + #endif From 6583864597136a7b41ab7abe0613b825333510b7 Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Wed, 29 Aug 2018 19:19:20 -0700 Subject: [PATCH 06/13] AVX2 implementation of interleave_4x4() --- libraries/audio/src/AudioHRTF.cpp | 6 +++- libraries/audio/src/avx2/AudioHRTF_avx2.cpp | 37 +++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/libraries/audio/src/AudioHRTF.cpp b/libraries/audio/src/AudioHRTF.cpp index 0f87df2346..655527a65c 100644 --- a/libraries/audio/src/AudioHRTF.cpp +++ b/libraries/audio/src/AudioHRTF.cpp @@ -453,8 +453,12 @@ static void FIR_1x4(float* src, float* dst0, float* dst1, float* dst2, float* ds (*f)(src, dst0, dst1, dst2, dst3, coef, numFrames); // dispatch } +void interleave_4x4_AVX2(float* src0, float* src1, float* src2, float* src3, float* dst, int numFrames); + static void interleave_4x4(float* src0, float* src1, float* src2, float* src3, float* dst, int numFrames) { - interleave_4x4_SSE(src0, src1, src2, src3, dst, numFrames); + + static auto f = cpuSupportsAVX2() ? interleave_4x4_AVX2 : interleave_4x4_SSE; + (*f)(src0, src1, src2, src3, dst, numFrames); // dispatch } void biquad2_4x4_AVX2(float* src, float* dst, float coef[5][8], float state[3][8], int numFrames); diff --git a/libraries/audio/src/avx2/AudioHRTF_avx2.cpp b/libraries/audio/src/avx2/AudioHRTF_avx2.cpp index 0c3c6b5096..9000df367f 100644 --- a/libraries/audio/src/avx2/AudioHRTF_avx2.cpp +++ b/libraries/audio/src/avx2/AudioHRTF_avx2.cpp @@ -87,6 +87,43 @@ void FIR_1x4_AVX2(float* src, float* dst0, float* dst1, float* dst2, float* dst3 _mm256_zeroupper(); } +// 4 channel planar to interleaved +void interleave_4x4_AVX2(float* src0, float* src1, float* src2, float* src3, float* dst, int numFrames) { + + assert(numFrames % 8 == 0); + + for (int i = 0; i < numFrames; i += 8) { + + __m256 x0 = _mm256_loadu_ps(&src0[i]); + __m256 x1 = _mm256_loadu_ps(&src1[i]); + __m256 x2 = _mm256_loadu_ps(&src2[i]); + __m256 x3 = _mm256_loadu_ps(&src3[i]); + + // interleave (4x4 matrix transpose) + __m256 t0 = _mm256_unpacklo_ps(x0, x1); + __m256 t1 = _mm256_unpackhi_ps(x0, x1); + __m256 t2 = _mm256_unpacklo_ps(x2, x3); + __m256 t3 = _mm256_unpackhi_ps(x2, x3); + + x0 = _mm256_shuffle_ps(t0, t2, _MM_SHUFFLE(1,0,1,0)); + x1 = _mm256_shuffle_ps(t0, t2, _MM_SHUFFLE(3,2,3,2)); + x2 = _mm256_shuffle_ps(t1, t3, _MM_SHUFFLE(1,0,1,0)); + x3 = _mm256_shuffle_ps(t1, t3, _MM_SHUFFLE(3,2,3,2)); + + t0 = _mm256_permute2f128_ps(x0, x1, 0x20); + t1 = _mm256_permute2f128_ps(x2, x3, 0x20); + t2 = _mm256_permute2f128_ps(x0, x1, 0x31); + t3 = _mm256_permute2f128_ps(x2, x3, 0x31); + + _mm256_storeu_ps(&dst[4*i+0], t0); + _mm256_storeu_ps(&dst[4*i+8], t1); + _mm256_storeu_ps(&dst[4*i+16], t2); + _mm256_storeu_ps(&dst[4*i+24], t3); + } + + _mm256_zeroupper(); +} + // process 2 cascaded biquads on 4 channels (interleaved) // biquads are computed in parallel, by adding one sample of delay void biquad2_4x4_AVX2(float* src, float* dst, float coef[5][8], float state[3][8], int numFrames) { From 4b7ca76ebdecd76950acb7b2f0daecc174a397bd Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Thu, 30 Aug 2018 14:15:57 -0700 Subject: [PATCH 07/13] Create correct folder. --- libraries/shared/src/shared/FileUtils.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libraries/shared/src/shared/FileUtils.cpp b/libraries/shared/src/shared/FileUtils.cpp index 9bdd65bf11..0709a53602 100644 --- a/libraries/shared/src/shared/FileUtils.cpp +++ b/libraries/shared/src/shared/FileUtils.cpp @@ -156,10 +156,12 @@ bool FileUtils::canCreateFile(const QString& fullPath) { qDebug(shared) << "unable to overwrite file '" << fullPath << "'"; return false; } - QDir dir(fileInfo.absolutePath()); + + QString absolutePath = fileInfo.absolutePath(); + QDir dir(absolutePath); if (!dir.exists()) { - if (!dir.mkpath(fullPath)) { - qDebug(shared) << "unable to create dir '" << dir.absolutePath() << "'"; + if (!dir.mkpath(absolutePath)) { + qDebug(shared) << "unable to create dir '" << absolutePath << "'"; return false; } } From 0f6fdef9284c95bc8a68e031bca7796618ec519d Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Thu, 30 Aug 2018 15:06:05 -0700 Subject: [PATCH 08/13] Fixed compilation error (within #ifdef) --- libraries/fbx/src/OBJReader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/fbx/src/OBJReader.cpp b/libraries/fbx/src/OBJReader.cpp index 501fb72130..c46a1e234c 100644 --- a/libraries/fbx/src/OBJReader.cpp +++ b/libraries/fbx/src/OBJReader.cpp @@ -273,7 +273,7 @@ void OBJReader::parseMaterialLibrary(QIODevice* device) { " diffuse texture:" << currentMaterial.diffuseTextureFilename << " specular texture:" << currentMaterial.specularTextureFilename << " emissive texture:" << currentMaterial.emissiveTextureFilename << - " bump texture:" << currentMaterial.bumpTextureFilename; + " bump texture:" << currentMaterial.bumpTextureFilename << " opacity texture:" << currentMaterial.opacityTextureFilename; #endif return; From 727bd6b05af29d3edd9b3d23a34428418e553712 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 31 Aug 2018 13:31:26 -0700 Subject: [PATCH 09/13] don't bid for simulation ownership of locked things --- libraries/physics/src/EntityMotionState.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index 925cfee740..2c130274bc 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -778,8 +778,10 @@ void EntityMotionState::computeCollisionGroupAndMask(int32_t& group, int32_t& ma bool EntityMotionState::shouldSendBid() const { // NOTE: this method is only ever called when the entity's simulation is NOT locally owned - return _body->isActive() && (_region == workload::Region::R1) && - glm::max(glm::max(VOLUNTEER_SIMULATION_PRIORITY, _bumpedPriority), _entity->getScriptSimulationPriority()) >= _entity->getSimulationPriority(); + return _body->isActive() + && (_region == workload::Region::R1) + && glm::max(glm::max(VOLUNTEER_SIMULATION_PRIORITY, _bumpedPriority), _entity->getScriptSimulationPriority()) >= _entity->getSimulationPriority() + && !_entity->getLocked(); } uint8_t EntityMotionState::computeFinalBidPriority() const { From 96aa0549be8d21d05ea5b3826b5d9a869d50c225 Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Sat, 1 Sep 2018 12:08:49 -0700 Subject: [PATCH 10/13] AVX2 implementation of crossfade_4x2() --- libraries/audio/src/AudioHRTF.cpp | 6 ++- libraries/audio/src/avx2/AudioHRTF_avx2.cpp | 57 +++++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/libraries/audio/src/AudioHRTF.cpp b/libraries/audio/src/AudioHRTF.cpp index 655527a65c..eea01b703b 100644 --- a/libraries/audio/src/AudioHRTF.cpp +++ b/libraries/audio/src/AudioHRTF.cpp @@ -469,8 +469,12 @@ static void biquad2_4x4(float* src, float* dst, float coef[5][8], float state[3] (*f)(src, dst, coef, state, numFrames); // dispatch } +void crossfade_4x2_AVX2(float* src, float* dst, const float* win, int numFrames); + static void crossfade_4x2(float* src, float* dst, const float* win, int numFrames) { - crossfade_4x2_SSE(src, dst, win, numFrames); + + static auto f = cpuSupportsAVX2() ? crossfade_4x2_AVX2 : crossfade_4x2_SSE; + (*f)(src, dst, win, numFrames); // dispatch } static void interpolate(const float* src0, const float* src1, float* dst, float frac, float gain) { diff --git a/libraries/audio/src/avx2/AudioHRTF_avx2.cpp b/libraries/audio/src/avx2/AudioHRTF_avx2.cpp index 9000df367f..b82098b72f 100644 --- a/libraries/audio/src/avx2/AudioHRTF_avx2.cpp +++ b/libraries/audio/src/avx2/AudioHRTF_avx2.cpp @@ -169,4 +169,61 @@ void biquad2_4x4_AVX2(float* src, float* dst, float coef[5][8], float state[3][8 _mm256_zeroupper(); } +// crossfade 4 inputs into 2 outputs with accumulation (interleaved) +void crossfade_4x2_AVX2(float* src, float* dst, const float* win, int numFrames) { + + assert(numFrames % 8 == 0); + + for (int i = 0; i < numFrames; i += 8) { + + __m256 f0 = _mm256_loadu_ps(&win[i]); + + __m256 x0 = _mm256_castps128_ps256(_mm_loadu_ps(&src[4*i+0])); + __m256 x1 = _mm256_castps128_ps256(_mm_loadu_ps(&src[4*i+4])); + __m256 x2 = _mm256_castps128_ps256(_mm_loadu_ps(&src[4*i+8])); + __m256 x3 = _mm256_castps128_ps256(_mm_loadu_ps(&src[4*i+12])); + + x0 = _mm256_insertf128_ps(x0, _mm_loadu_ps(&src[4*i+16]), 1); + x1 = _mm256_insertf128_ps(x1, _mm_loadu_ps(&src[4*i+20]), 1); + x2 = _mm256_insertf128_ps(x2, _mm_loadu_ps(&src[4*i+24]), 1); + x3 = _mm256_insertf128_ps(x3, _mm_loadu_ps(&src[4*i+28]), 1); + + __m256 y0 = _mm256_loadu_ps(&dst[2*i+0]); + __m256 y1 = _mm256_loadu_ps(&dst[2*i+8]); + + // deinterleave (4x4 matrix transpose) + __m256 t0 = _mm256_unpacklo_ps(x0, x1); + __m256 t1 = _mm256_unpackhi_ps(x0, x1); + __m256 t2 = _mm256_unpacklo_ps(x2, x3); + __m256 t3 = _mm256_unpackhi_ps(x2, x3); + + x0 = _mm256_shuffle_ps(t0, t2, _MM_SHUFFLE(1,0,1,0)); + x1 = _mm256_shuffle_ps(t0, t2, _MM_SHUFFLE(3,2,3,2)); + x2 = _mm256_shuffle_ps(t1, t3, _MM_SHUFFLE(1,0,1,0)); + x3 = _mm256_shuffle_ps(t1, t3, _MM_SHUFFLE(3,2,3,2)); + + // crossfade + x0 = _mm256_sub_ps(x0, x2); + x1 = _mm256_sub_ps(x1, x3); + x2 = _mm256_fmadd_ps(f0, x0, x2); + x3 = _mm256_fmadd_ps(f0, x1, x3); + + // interleave + t0 = _mm256_unpacklo_ps(x2, x3); + t1 = _mm256_unpackhi_ps(x2, x3); + + x0 = _mm256_permute2f128_ps(t0, t1, 0x20); + x1 = _mm256_permute2f128_ps(t0, t1, 0x31); + + // accumulate + y0 = _mm256_add_ps(y0, x0); + y1 = _mm256_add_ps(y1, x1); + + _mm256_storeu_ps(&dst[2*i+0], y0); + _mm256_storeu_ps(&dst[2*i+8], y1); + } + + _mm256_zeroupper(); +} + #endif From 94e8ee99f5cade6f6f9a9bcf179c6b229a05cc37 Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Mon, 3 Sep 2018 13:06:49 -0700 Subject: [PATCH 11/13] AVX2 implementation of interpolate() --- libraries/audio/src/AudioHRTF.cpp | 6 +++++- libraries/audio/src/avx2/AudioHRTF_avx2.cpp | 22 +++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/libraries/audio/src/AudioHRTF.cpp b/libraries/audio/src/AudioHRTF.cpp index eea01b703b..b52f624620 100644 --- a/libraries/audio/src/AudioHRTF.cpp +++ b/libraries/audio/src/AudioHRTF.cpp @@ -477,8 +477,12 @@ static void crossfade_4x2(float* src, float* dst, const float* win, int numFrame (*f)(src, dst, win, numFrames); // dispatch } +void interpolate_AVX2(const float* src0, const float* src1, float* dst, float frac, float gain); + static void interpolate(const float* src0, const float* src1, float* dst, float frac, float gain) { - interpolate_SSE(src0, src1, dst, frac, gain); + + static auto f = cpuSupportsAVX2() ? interpolate_AVX2 : interpolate_SSE; + (*f)(src0, src1, dst, frac, gain); // dispatch } #else // portable reference code diff --git a/libraries/audio/src/avx2/AudioHRTF_avx2.cpp b/libraries/audio/src/avx2/AudioHRTF_avx2.cpp index b82098b72f..aadbb2d0cd 100644 --- a/libraries/audio/src/avx2/AudioHRTF_avx2.cpp +++ b/libraries/audio/src/avx2/AudioHRTF_avx2.cpp @@ -226,4 +226,26 @@ void crossfade_4x2_AVX2(float* src, float* dst, const float* win, int numFrames) _mm256_zeroupper(); } +// linear interpolation with gain +void interpolate_AVX2(const float* src0, const float* src1, float* dst, float frac, float gain) { + + __m256 f0 = _mm256_set1_ps(gain * (1.0f - frac)); + __m256 f1 = _mm256_set1_ps(gain * frac); + + static_assert(HRTF_TAPS % 8 == 0, "HRTF_TAPS must be a multiple of 8"); + + for (int k = 0; k < HRTF_TAPS; k += 8) { + + __m256 x0 = _mm256_loadu_ps(&src0[k]); + __m256 x1 = _mm256_loadu_ps(&src1[k]); + + x0 = _mm256_mul_ps(f0, x0); + x0 = _mm256_fmadd_ps(f1, x1, x0); + + _mm256_storeu_ps(&dst[k], x0); + } + + _mm256_zeroupper(); +} + #endif From f5b7232f58906e82e24c22b12e778746f946b033 Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Mon, 3 Sep 2018 14:00:30 -0700 Subject: [PATCH 12/13] Cleanup --- libraries/audio/src/AudioHRTF.cpp | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/libraries/audio/src/AudioHRTF.cpp b/libraries/audio/src/AudioHRTF.cpp index b52f624620..b639301404 100644 --- a/libraries/audio/src/AudioHRTF.cpp +++ b/libraries/audio/src/AudioHRTF.cpp @@ -446,41 +446,32 @@ static void interpolate_SSE(const float* src0, const float* src1, float* dst, fl void FIR_1x4_AVX2(float* src, float* dst0, float* dst1, float* dst2, float* dst3, float coef[4][HRTF_TAPS], int numFrames); void FIR_1x4_AVX512(float* src, float* dst0, float* dst1, float* dst2, float* dst3, float coef[4][HRTF_TAPS], int numFrames); +void interleave_4x4_AVX2(float* src0, float* src1, float* src2, float* src3, float* dst, int numFrames); +void biquad2_4x4_AVX2(float* src, float* dst, float coef[5][8], float state[3][8], int numFrames); +void crossfade_4x2_AVX2(float* src, float* dst, const float* win, int numFrames); +void interpolate_AVX2(const float* src0, const float* src1, float* dst, float frac, float gain); static void FIR_1x4(float* src, float* dst0, float* dst1, float* dst2, float* dst3, float coef[4][HRTF_TAPS], int numFrames) { - static auto f = cpuSupportsAVX512() ? FIR_1x4_AVX512 : (cpuSupportsAVX2() ? FIR_1x4_AVX2 : FIR_1x4_SSE); (*f)(src, dst0, dst1, dst2, dst3, coef, numFrames); // dispatch } -void interleave_4x4_AVX2(float* src0, float* src1, float* src2, float* src3, float* dst, int numFrames); - static void interleave_4x4(float* src0, float* src1, float* src2, float* src3, float* dst, int numFrames) { - static auto f = cpuSupportsAVX2() ? interleave_4x4_AVX2 : interleave_4x4_SSE; (*f)(src0, src1, src2, src3, dst, numFrames); // dispatch } -void biquad2_4x4_AVX2(float* src, float* dst, float coef[5][8], float state[3][8], int numFrames); - static void biquad2_4x4(float* src, float* dst, float coef[5][8], float state[3][8], int numFrames) { - static auto f = cpuSupportsAVX2() ? biquad2_4x4_AVX2 : biquad2_4x4_SSE; (*f)(src, dst, coef, state, numFrames); // dispatch } -void crossfade_4x2_AVX2(float* src, float* dst, const float* win, int numFrames); - static void crossfade_4x2(float* src, float* dst, const float* win, int numFrames) { - static auto f = cpuSupportsAVX2() ? crossfade_4x2_AVX2 : crossfade_4x2_SSE; (*f)(src, dst, win, numFrames); // dispatch } -void interpolate_AVX2(const float* src0, const float* src1, float* dst, float frac, float gain); - static void interpolate(const float* src0, const float* src1, float* dst, float frac, float gain) { - static auto f = cpuSupportsAVX2() ? interpolate_AVX2 : interpolate_SSE; (*f)(src0, src1, dst, frac, gain); // dispatch } From 24cf4adb44a55d79fe3a97f1a72dc4c2b238032f Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Tue, 4 Sep 2018 09:08:42 -0700 Subject: [PATCH 13/13] Fix MS17902: Prevent case where My Purchases says Open instead of Uninstall --- interface/src/commerce/QmlCommerce.cpp | 59 +++++++++++++++----------- 1 file changed, 34 insertions(+), 25 deletions(-) diff --git a/interface/src/commerce/QmlCommerce.cpp b/interface/src/commerce/QmlCommerce.cpp index 1c6600cf3f..06da18148f 100644 --- a/interface/src/commerce/QmlCommerce.cpp +++ b/interface/src/commerce/QmlCommerce.cpp @@ -40,11 +40,9 @@ QmlCommerce::QmlCommerce() { connect(ledger.data(), &Ledger::transferAssetToUsernameResult, this, &QmlCommerce::transferAssetToUsernameResult); connect(ledger.data(), &Ledger::availableUpdatesResult, this, &QmlCommerce::availableUpdatesResult); connect(ledger.data(), &Ledger::updateItemResult, this, &QmlCommerce::updateItemResult); - + auto accountManager = DependencyManager::get(); - connect(accountManager.data(), &AccountManager::usernameChanged, this, [&]() { - setPassphrase(""); - }); + connect(accountManager.data(), &AccountManager::usernameChanged, this, [&]() { setPassphrase(""); }); _appsPath = PathUtils::getAppDataPath() + "Apps/"; } @@ -105,7 +103,11 @@ void QmlCommerce::balance() { } } -void QmlCommerce::inventory(const QString& editionFilter, const QString& typeFilter, const QString& titleFilter, const int& page, const int& perPage) { +void QmlCommerce::inventory(const QString& editionFilter, + const QString& typeFilter, + const QString& titleFilter, + const int& page, + const int& perPage) { auto ledger = DependencyManager::get(); auto wallet = DependencyManager::get(); QStringList cachedPublicKeys = wallet->listPublicKeys(); @@ -166,24 +168,30 @@ void QmlCommerce::certificateInfo(const QString& certificateId) { ledger->certificateInfo(certificateId); } -void QmlCommerce::transferAssetToNode(const QString& nodeID, const QString& certificateID, const int& amount, const QString& optionalMessage) { +void QmlCommerce::transferAssetToNode(const QString& nodeID, + const QString& certificateID, + const int& amount, + const QString& optionalMessage) { auto ledger = DependencyManager::get(); auto wallet = DependencyManager::get(); QStringList keys = wallet->listPublicKeys(); if (keys.count() == 0) { - QJsonObject result{ { "status", "fail" },{ "message", "Uninitialized Wallet." } }; + QJsonObject result{ { "status", "fail" }, { "message", "Uninitialized Wallet." } }; return emit transferAssetToNodeResult(result); } QString key = keys[0]; ledger->transferAssetToNode(key, nodeID, certificateID, amount, optionalMessage); } -void QmlCommerce::transferAssetToUsername(const QString& username, const QString& certificateID, const int& amount, const QString& optionalMessage) { +void QmlCommerce::transferAssetToUsername(const QString& username, + const QString& certificateID, + const int& amount, + const QString& optionalMessage) { auto ledger = DependencyManager::get(); auto wallet = DependencyManager::get(); QStringList keys = wallet->listPublicKeys(); if (keys.count() == 0) { - QJsonObject result{ { "status", "fail" },{ "message", "Uninitialized Wallet." } }; + QJsonObject result{ { "status", "fail" }, { "message", "Uninitialized Wallet." } }; return emit transferAssetToUsernameResult(result); } QString key = keys[0]; @@ -194,10 +202,7 @@ void QmlCommerce::replaceContentSet(const QString& itemHref, const QString& cert auto ledger = DependencyManager::get(); ledger->updateLocation(certificateID, DependencyManager::get()->getPlaceName(), true); qApp->replaceDomainContent(itemHref); - QJsonObject messageProperties = { - { "status", "SuccessfulRequestToReplaceContent" }, - { "content_set_url", itemHref } - }; + QJsonObject messageProperties = { { "status", "SuccessfulRequestToReplaceContent" }, { "content_set_url", itemHref } }; UserActivityLogger::getInstance().logAction("replace_domain_content", messageProperties); emit contentSetChanged(itemHref); @@ -214,10 +219,7 @@ QString QmlCommerce::getInstalledApps(const QString& justInstalledAppID) { QDir directory(_appsPath); QStringList apps = directory.entryList(QStringList("*.app.json")); - foreach(QString appFileName, apps) { - installedAppsFromMarketplace += appFileName; - installedAppsFromMarketplace += ","; - + foreach (QString appFileName, apps) { // If we were supplied a "justInstalledAppID" argument, that means we're entering this function // to get the new list of installed apps immediately after installing an app. // In that case, the app we installed may not yet have its associated script running - @@ -243,10 +245,12 @@ QString QmlCommerce::getInstalledApps(const QString& justInstalledAppID) { // delete the .app.json from the user's local disk. if (!runningScripts.contains(scriptURL)) { if (!appFile.remove()) { - qCWarning(commerce) - << "Couldn't delete local .app.json file (app's script isn't running). App filename is:" - << appFileName; + qCWarning(commerce) << "Couldn't delete local .app.json file (app's script isn't running). App filename is:" + << appFileName; } + } else { + installedAppsFromMarketplace += appFileName; + installedAppsFromMarketplace += ","; } } else { qCDebug(commerce) << "Couldn't open local .app.json file for reading."; @@ -317,7 +321,9 @@ bool QmlCommerce::uninstallApp(const QString& itemHref) { // Read from the file to know what .js script to stop QFile appFile(_appsPath + "/" + appHref.fileName()); if (!appFile.open(QIODevice::ReadOnly)) { - qCDebug(commerce) << "Couldn't open local .app.json file for deletion. Cannot continue with app uninstallation. App filename is:" << appHref.fileName(); + qCDebug(commerce) + << "Couldn't open local .app.json file for deletion. Cannot continue with app uninstallation. App filename is:" + << appHref.fileName(); return false; } QJsonDocument appFileJsonDocument = QJsonDocument::fromJson(appFile.readAll()); @@ -325,13 +331,15 @@ bool QmlCommerce::uninstallApp(const QString& itemHref) { QString scriptUrl = appFileJsonObject["scriptURL"].toString(); if (!DependencyManager::get()->stopScript(scriptUrl.trimmed(), false)) { - qCWarning(commerce) << "Couldn't stop script during app uninstall. Continuing anyway. ScriptURL is:" << scriptUrl.trimmed(); + qCWarning(commerce) << "Couldn't stop script during app uninstall. Continuing anyway. ScriptURL is:" + << scriptUrl.trimmed(); } // Delete the .app.json from the filesystem // remove() closes the file first. if (!appFile.remove()) { - qCWarning(commerce) << "Couldn't delete local .app.json file during app uninstall. Continuing anyway. App filename is:" << appHref.fileName(); + qCWarning(commerce) << "Couldn't delete local .app.json file during app uninstall. Continuing anyway. App filename is:" + << appHref.fileName(); } QFileInfo appFileInfo(appFile); @@ -352,7 +360,8 @@ bool QmlCommerce::openApp(const QString& itemHref) { QJsonObject appFileJsonObject = appFileJsonDocument.object(); QString homeUrl = appFileJsonObject["homeURL"].toString(); - auto tablet = dynamic_cast(DependencyManager::get()->getTablet("com.highfidelity.interface.tablet.system")); + auto tablet = dynamic_cast( + DependencyManager::get()->getTablet("com.highfidelity.interface.tablet.system")); if (homeUrl.contains(".qml", Qt::CaseInsensitive)) { tablet->loadQMLSource(homeUrl); } else if (homeUrl.contains(".html", Qt::CaseInsensitive)) { @@ -377,7 +386,7 @@ void QmlCommerce::updateItem(const QString& certificateId) { auto wallet = DependencyManager::get(); QStringList keys = wallet->listPublicKeys(); if (keys.count() == 0) { - QJsonObject result{ { "status", "fail" },{ "message", "Uninitialized Wallet." } }; + QJsonObject result{ { "status", "fail" }, { "message", "Uninitialized Wallet." } }; return emit updateItemResult(result); } QString key = keys[0];