4

我正在使用 SSE2/AVX 内在函数在 C++ 中编写符合 HLSL float4 的类型,目前我正在实现 HLSL 中可用于 float4 的所有 set-swizzle 操作。我试图找出一个最佳的 SSE2 实现来处理涉及(swizzle)设置 2 或 3 个组件的 set-swizzle 操作(因为使用一个 SSE shuffle 操作来实现 4-component set-swizzles 是微不足道的)。例如,如果没有至少 4/5 SSE shuffle ops,我想不出更好的方法来实现 say 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您可以通过使用可以以一种有限的方式组合两个向量的事实来到达某个地方。这是我的尝试:

// 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 回答