SSE2/AVX 組み込み関数を使用して C++ で HLSL float4 準拠の型を作成しています。現在、HLSL の float4 で使用できるすべてのセット スウィズル操作を実装しています。2 つまたは 3 つのコンポーネントの設定 (スウィズル) を含むセット スウィズル操作に対処するための最適な SSE2 実装を見つけようとしています (4 コンポーネントのセット スウィズルは 1 つの SSE シャッフル操作で実装するのは簡単なので)。たとえば、少なくとも 4/5 の SSE シャッフル ops なしで set_wxy を実装するより良い方法を理解することはできません。
inline/__forceinline void float4::set_wxy(const float4& x)
{
float4 tmp2 = *this;
tmp2.set_wxyz(x); // set_wxyz = 1 x _mm_shuffle_ps
const __m128 xyw_tmp = tmp2.zxyw().data; // zxyw() = 1 x _mm_shuffle_ps
const __m128 z_tmp = zxyw().data; // zxyw() = 1 x _mm_shuffle_ps
tmp2 = _mm_move_ss(xyw_tmp, z_tmp);
set_zxyw(tmp2); // set_zxyw() = 1 x _mm_shuffle_ps
}
SSE2以外の操作を使用せずに、より良い実装のアイデアを持っている人はいますか? SSE4/AVX で _mm_blend_ps を認識しているため、プリプロセッサ条件を介して使用できる場合に使用しますが、少なくとも SSE2 のみのコード パスをサポートしたいと考えています。前もって感謝します!
編集: この関数の動作の例は次のとおりです。
float4 k(5,5,5,5);
k.set_wxy(float4(1,2,3,4));
// now k == (2, 3, 5, 1)
基本的に set_wxy は、x、y、z の引数をこの順序で使用して w、x、y コンポーネントを設定します。元の z 値は保持されます。