0

当我计算 alpha blending 时,我需要将 8bit alpha 转换为 float,即 alpha/255。因为 NEON 没有分频器,所以我想要 alpha * 1/255。那么如何在 q1 中生成 1/255 向量呢?

vmov.f32 q1,#0.003921569 总是报错。

vmov.u32 q1, #255 vrecpe.u32 q1, q1 在 f32 中总是生成 0。

4

4 回答 4

2

你很亲密。在取倒数之前,您需要将 255 的向量转换为浮点数。

vmov.u32        q0, #255
vcvt.f32.u32    q0, q0
vrecpe.f32      q1, q0

请注意,它vrecpe有少量错误,但它应该足够接近 Alpha 混合。

于 2012-10-31T15:18:36.397 回答
1

对于微不足道的 alpha 混合,您真的不需要为浮点数烦恼。鉴于:

y = rint(x * a / 255.0);

对于任何没有浮点的 8 位输入,您可以使用以下方法获得相同的结果:

t = x * a;
t += (t + 0x80) >> 8;
y = (t + 0x80) >> 8;

类似于:

; given eight 8-bit x in d0, and eight 8-bit a in d1
    vmull.u8 q2, d0, d1
    vrsra.u16 q2, q2, #8
    vrshrn.u16 d2, q2, #8
; result is eight 8-bit (s*a/255) in d2

通常,最后两个操作实现了从 16 位输入到 8 位输出的全面除以 255;但它们依赖于 8×8 乘法的有限范围。如果 16 位中间值不仅仅是乘法的结果,那么可能需要进行钳位,并且由于没有vqrsra序列变得更长:

; given eight 8-bit x in d0, and eight 8-bit a in d1
    vmull.u8 q2, d0, d1
    ???
    vrshr.u16 q3, q2, #8
    vqadd.u16 q2, q2, q3
    vqrshrn.u16 d2, q2, #8
; result is eight 8-bit (s*a/255) in d2
于 2014-11-11T05:13:16.003 回答
1

不是 100% 的答案,但由于到目前为止你没有得到任何其他答案,我想我会帮助你开始;

据我记得,您可以使用的浮点子集vmov.f32非常有限,因此如果您想加载任意浮点数,您需要将其存储为常量并使用vldr. 像这样的事情应该这样做;

ldr r1,=floats 

vldr.32 s0,[r1]     @1/256

floats:
.float 0.003921569

“不是 100%”部分是我没有查看向量指令,所以我不确定您是否可以s0立即在此代码中替换,或者您是否需要在加载后q1移至。s0q1

于 2012-10-31T07:26:15.510 回答
0

可能你想要 float32x4_t x = vdupq_n_32(1.0f / 255);

编译器负责计算常数,vdup 指令将值广播到向量的所有四个通道

vdup 指令支持 NEON 标量和 ARM 寄存器作为源操作数

于 2014-04-24T15:13:23.503 回答