當我計算阿爾法混合,我需要轉換8位阿爾法浮動,這將是阿爾法/ 255。因爲NEON沒有分裂,所以我想alpha * 1/255。那麼如何在q1中生成1/255向量呢?如何使用霓虹燈創建1/255 f32矢量?
vmov.f32 q1,#0.003921569總是報告錯誤。
vmov.u32 q1,#255 vrecpe.u32 q1,q1總是在f32中產生0。
當我計算阿爾法混合,我需要轉換8位阿爾法浮動,這將是阿爾法/ 255。因爲NEON沒有分裂,所以我想alpha * 1/255。那麼如何在q1中生成1/255向量呢?如何使用霓虹燈創建1/255 f32矢量?
vmov.f32 q1,#0.003921569總是報告錯誤。
vmov.u32 q1,#255 vrecpe.u32 q1,q1總是在f32中產生0。
你就近了。在採取倒數之前,您需要將255的向量轉換爲浮點數。
vmov.u32 q0, #255
vcvt.f32.u32 q0, q0
vrecpe.f32 q1, q0
注意,vrecpe
有錯誤的量小,但它應該是alpha混合足夠接近。
不是100%的答案,但由於你迄今沒有得到任何其他人,我以爲我會幫你開始;
從我記得,你可以使用vmov.f32
加載浮動的子集是非常有限的,所以如果你想加載一個任意的浮動,你需要將它存儲爲一個常量,並使用vldr
從常量池加載它。像這樣的東西應該這樣做;
ldr r1,=floats
vldr.32 s0,[r1] @1/256
floats:
.float 0.003921569
的「不是100%」的部分是,我還沒有進去看了向量指令,所以我不能確定是否可以在此代碼替換s0
與q1
馬上或者如果你需要移動s0
到加載後加載q1
。
感謝您的回答!是的,霓虹燈也可以加載恆定。 asm代碼嵌入在C中,所以我也可以在c中計算float常量。但霓虹燈不能像r0那樣移動寄存器到Q0/S0,對嗎?也許我必須將常量傳遞給變量並將可變地址傳遞給嵌入的asm代碼。 –
@RichardZhao:當然你可以從r0移動到s0。 'vmov s0,r0'。你也可以將一個預先計算好的常量直接加載到's0'或'q0',這可能是你真正想要的。 –
可能你想要 float32x4_t x = vdupq_n_32(1.0f/255);
編譯器負責計算不變,VDUP指令值廣播到向量的所有四個車道
的VDUP指令支持NEON標量和ARM寄存器作爲源操作數
你真的needn」不必擔心浮點操作可能會導致一個簡單的alpha混合。鑑於:
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
一般最後兩個
y = rint(x * a/255.0);
可以使用得到相同的結果對於任何8位輸入,而不浮點操作實現了從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
一般來說,如果你有8個數據,不想轉換爲浮點型來進行alpha混合;您可以使用16位定點算法獲得足夠的精度,從而可以在每個矢量中保留更多像素。 –