0

アルファブレンディングを計算するときは、8ビットのアルファをfloatに変換する必要があります。これはalpha/255になります。NEONには除算がないので、アルファ*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のベクトルをfloatに変換する必要があります。

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

vrecpe多少の誤差がありますが、アルファブレンディングには十分に近いはずです。

于 2012-10-31T15:18:36.397 に答える
1

100%の答えではありませんが、これまで他に何も得られなかったので、私はあなたが始めるのを手伝うと思いました。

私が覚えていることから、使用してロードできるフロートのサブセットvmov.f32は非常に限られているため、任意のフロートをロードする場合は、定数として格納し、を使用して定数プールからロードする必要がありますvldr。このような何かがそれを行う必要があります。

ldr r1,=floats 

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

floats:
.float 0.003921569

「100%ではない」部分は、ベクトル命令を調べていないため、このコードでs0すぐに置き換えることができるかどうか、またはロード後に移動する必要があるかどうかがわかりません。q1s0q1

于 2012-10-31T07:26:15.510 に答える
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

一般に、最後の2つの演算は、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 に答える
0

おそらくfloat32x4_tx= vdupq_n_32(1.0f / 255);が必要です。

コンパイラは定数の計算に注意を払い、vdup命令は値をベクトルの4つのレーンすべてにブロードキャストします

vdup命令は、ソースオペランドとしてNEONスカラーとARMレジスタをサポートします

于 2014-04-24T15:13:23.503 に答える