4

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 値は保持されます。

4

1 に答える 1

1

HLSL のこの行をエミュレートしようとしていますよね?

vec2.wxy = vec1.xyz;

_mm_shuffle_psある種の限られた方法で 2 つのベクトルを組み合わせることができるという事実を利用することで、どこかに到達できます。ここに私の刺し傷があります:

// xyzw is vec1, XYZW is vec2
__m128 xxZZ = _mm_shuffle_ps(vec1, vec2, _MM_SHUFFLE(2, 2, 0, 0));
__m128 ZxZx = _mm_shuffle_ps(xxZZ, xxZZ, _MM_SHUFFLE(0, 2, 0, 2));
__m128 yzZx = _mm_shuffle_ps(vec1, ZxZx, _MM_SHUFFLE(1, 0, 2, 1));

vec2 = yzZx;
于 2012-07-08T16:52:46.850 に答える