0

在特定情况下,我对如何通过 Neon 上的标量实现除法有点困惑。

在 c++ 上下文中,我使用非常基本的算法实现了对比效果:

if (currentEffect == "contrast_with_cpp")
{
    r += ((r - 128) / 2);
    g += ((g - 128) / 2);
    b += ((b - 128) / 2);
}   

我想将此算法移植到霓虹内在函数。

我试过了,但我对这种方法完全是新手,我无法在 Visual Studio 中调试这段代码。它在启动时编译并集成到 Windows Phone 应用程序中。

if (currentEffect == "contrast_with_neon") /* Experimental, not working *
{
    // To test
    copy_rgb = rgb;

    // Substract 128 from the copy, prevent it should be a signed variable

?

    // Get half value from copy and put it in another copy

    uint8x8x4_t otherCopy = interleaved;
    otherCopy.val[2] = vmul_n_f32(copy_rgb.val[2], 0.5);
    otherCopy.val[1] = vmul_n_f32(copy_rgb.val[1], 0.5);
    otherCopy.val[0] = vmul_n_f32(copy_rgb.val[0], 0.5);

    // Add it to the first copy

    copy_rgb.val[2] = vadd_u8(copy_rgb.val[2], otherCopy.val[2]);
    copy_rgb.val[1] = vadd_u8(copy_rgb.val[2], otherCopy.val[1]);
    copy_rgb.val[0] = vadd_u8(copy_rgb.val[2], otherCopy.val[0]);       

    rgb = copy_rgb;
}

这可以使用内在函数实现吗?

[编辑] 我猜颜色数据结构类似于这个

4

1 回答 1

0

不要在内在函数上浪费时间。这是一个真正的痛苦,尤其是 gcc。

在汇编中试试这个:

vmov.i16 qMdeian, #128 // put this line outside of loop
// -----------------------------------------------

vmovl.u8 qRed, dRed
vmovl.u8 qGrn, dGrn
vmovl.u8 qBlu, dBlu

vsub.s16 qRedTemp, qRed, qMedian
vsub.s16 qGrnTemp, qGrn, qMedian
vsub.s16 qBluTemp, qBlu, qMedian

vshr.s16 qRedTemp, #2
vshr.s16 qGrnTemp, #2
vshr.s16 qBluTemp, #2

vadd.s16 qRed, qRedTemp
vadd.s16 qGrn, qGrnTemp
vadd.s16 qBlu, qBluTemp

vqmovun.s16 dRed, qRed
vqmovun.s16 dGrn, qGrn
vqmovun.s16 dBlu, qBlu

如果确实在 255 处饱和,并且任何负值都将变为零,我认为这是有意的。

PS:你用浮动做什么?

于 2013-06-25T07:45:36.520 回答