2012-07-08 3 views
4

Я пишу HLSL float4-совместимый тип на C++ с встроенными функциями SSE2/AVX, и на данный момент я реализую все операции с набором-swizzle, доступные для float4 в HLSL. Я пытаюсь найти оптимальную реализацию SSE2 для обработки операций set-swizzle с участием (swizzle), устанавливающих 2 или 3 компонента (поскольку 4-компонентные набор-swizzles тривиальны для реализации с помощью одного SSE shuffle op). Например, я не могу понять, лучший способ реализовать сказать set_wxy без по крайней мере, 4/5 SSE перетасовка опса т.д .:Лучшая реализация SSE2 для float4 :: set_wxy (и других опций set-swizzle)?

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? поскольку я знаю _mm_blend_ps в SSE4/AVX, для которого я буду использовать, когда доступен через условные обозначения препроцессора, но я хочу поддерживать хотя бы один кодовый путь SSE2. Заранее спасибо!

EDIT: пример поведения этой функции:

float4 k(5,5,5,5); 
k.set_wxy(float4(1,2,3,4)); 
// now k == (2, 3, 5, 1) 

В основном set_wxy устанавливает W, X, Y компоненты, используя аргументы х, у, г в этом порядке, первоначальное значение г сохраняется.

+0

Что именно должно установить set_wxy? Я попытался вывести его из кода, но слишком много его скрыто. – harold

+0

@harold Хорошо. Я только что добавил дополнительную информацию о поведении этих функций. Надеюсь, это немного облегчит ситуацию. Спасибо за прочтение. –

+0

взгляните на источник DirectXMath в SDK Windows 8 ('DirectXMath.h'), он имеет очень быстрые SSE2-операции для swizzles и т. Д. (И его запись должна соответствовать DX & HLSL). TBH, вы, вероятно, могли бы использовать математику DX прямо, сэкономить усилия – Necrolis

ответ

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; 

 Смежные вопросы

  • Нет связанных вопросов^_^