2012-07-08 45 views
4

我正在使用SSE2/AVX內在函數編寫C++中的HLSL float4兼容類型,此刻我正在實現HLSL中用於float4的所有set-swizzle操作。我試圖找出一個最佳的SSE2實現來處理涉及(swizzle)設置2個或3個組件的set-swizzle操作(因爲使用一個SSE shuffle op實現4個組件集合 - swizzle是微不足道的)。例如,我不能沒有至少4/5 SSE洗牌OPS例如爲:找出實現一個更好的辦法說set_wxy對於float4 :: set_wxy(和其他set-swizzle操作符)更好的SSE2實現?

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設置W,X,使用X,Y,Z的參數以該順序y分量,原始Z值被保留。

+0

什麼是set_wxy應該這樣做,究竟是什麼?我試圖從代碼中推斷出來,但其中太多內容是隱藏的。 – harold 2012-07-08 16:09:41

+0

@harold好吧我剛剛添加了一些關於這些函數行爲的更多信息,我希望這可以清理一些東西。謝謝閱讀。 – 2012-07-08 16:25:40

+0

查看Windows 8 SDK('DirectXMath.h')中DirectXMath的源代碼,它具有非常快速的SSE2操作系統,用於swizzles等(並且它的編寫符合DX&HLSL)。 TBH,你可以直接使用DX數學,節省你的努力 – Necrolis 2012-07-08 16:29:35

回答

1

你想模仿HLSL的這一行,對吧?

vec2.wxy = vec1.xyz; 

您可以通過使用一個事實,即_mm_shuffle_ps可以在某種方式有限的結合兩個向量得到的地方。這是我的刺傷:

// 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;