当我计算alpha混合时,我需要将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。
答案 0 :(得分:2)
你很亲密。你需要在取倒数之前将255的向量转换为浮点数。
vmov.u32 q0, #255
vcvt.f32.u32 q0, q0
vrecpe.f32 q1, q0
请注意vrecpe
有少量错误,但它应该足够接近alpha混合。
答案 1 :(得分:1)
不是100%的答案,但是因为到目前为止你没有得到任何其他人,我以为我会帮助你开始;
根据我的记忆,您可以使用vmov.f32
加载的浮点子集非常有限,因此如果要加载任意浮点数,则需要将其存储为常量并从常量池加载它使用vldr
。像这样的东西应该这样做;
ldr r1,=floats
vldr.32 s0,[r1] @1/256
floats:
.float 0.003921569
“不是100%”部分是因为我没有查看向量说明,因此我不确定您是否可以在此代码中使用s0
立即替换q1
,或者如果您需要在加载后将s0
移至q1
。
答案 2 :(得分:1)
你真的不需要为浮点数而烦恼。给出:
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
答案 3 :(得分:0)
可能你想要的 float32x4_t x = vdupq_n_32(1.0f / 255);
编译器负责计算常量,vdup指令将值广播到向量的所有四个通道
vdup指令支持NEON标量和ARM寄存器作为源操作数