2

rgbからグレースケールに効率的に変換しようとしているので、ここからrgbaからグレースケールに変換する方法を説明する関数を取得しました。今、私は同じことをしようとしていますが、rgbだけを使用しています。いくつか変更しましたが、うまく機能していないようです。理由はわかりませんが、誰かが私の間違いを見ていますか?

void neon_asm_convert(uint8_t * __restrict dest, uint8_t * __restrict src, int numPixels)
{
    __asm__ volatile(
     "lsr %2, %2, #3 \n"
     "# build the three constants:  \n"
     "mov r4, #28                   \n" // Blue channel multiplier
     "mov r5, #151                  \n" // Green channel multiplier
     "mov r6, #77                   \n" // Red channel multiplier
     "vdup.8 d4, r4                 \n"
     "vdup.8 d5, r5                 \n"
     "vdup.8 d6, r6                 \n"
     "0: \n"
     "# load 8 pixels: \n"  //RGBR
     "vld4.8 {d0-d3}, [%1]! \n"
     "# do the weight average: \n"
     "vmull.u8 q7, d0, d4 \n"
     "vmlal.u8 q7, d1, d5 \n"
     "vmlal.u8 q7, d2, d6 \n"
     "# shift and store: \n"
     "vshrn.u16 d7, q7, #8 \n" // Divide q3 by 256 and store in the d7
     "vst1.8 {d7}, [%0]! \n"
     "subs %2, %2, #1 \n" // Decrement iteration count

     "# load 8 pixels: \n"
     "vld4.8 {d8-d11}, [%1]! \n" //Other GBRG
     "# do the weight average: \n"
     "vmull.u8 q7, d3, d4 \n"
     "vmlal.u8 q7, d8, d5 \n"
     "vmlal.u8 q7, d9, d6 \n"
     "# shift and store: \n"
     "vshrn.u16 d7, q7, #8 \n" // Divide q3 by 256 and store in the d7
     "vst1.8 {d7}, [%0]! \n"
     "subs %2, %2, #1 \n" // Decrement iteration count

     "# load 8 pixels: \n"
     "vld4.8 {d0-d3}, [%1]! \n"
     "# do the weight average: \n"
     "vmull.u8 q7, d10, d4 \n"
     "vmlal.u8 q7, d11, d5 \n"
     "vmlal.u8 q7, d0, d6 \n"
     "# shift and store: \n"
     "vshrn.u16 d7, q7, #8 \n" // Divide q3 by 256 and store in the d7
     "vst1.8 {d7}, [%0]! \n"
     "subs %2, %2, #1 \n" // Decrement iteration count


     "# do the weight average: \n"
     "vmull.u8 q7, d1, d4 \n"
     "vmlal.u8 q7, d2, d5 \n"
     "vmlal.u8 q7, d3, d6 \n"
     "# shift and store: \n"
     "vshrn.u16 d7, q7, #8 \n" // Divide q3 by 256 and store in the d7
     "vst1.8 {d7}, [%0]! \n"

     "subs %2, %2, #1 \n" // Decrement iteration count



     "bne 0b \n" // Repeat unil iteration count is not zero
     :
     : "r"(dest), "r"(src), "r"(numPixels)
     : "r4", "r5", "r6"
    );
}
4

3 に答える 3

2

あなたは使用する必要があります"vld3.8 {d0-d2}, [%1]! \n"

http://hilbert-space.de/?p=22も参照してください。

于 2012-01-22T02:02:18.740 に答える
1

Vasileは正しいです。VLD3を使用して24ビットピクセルをロードします。

また、4VSTxに対して3VLDxがあります。実際、コードは非常に奇妙です...

コードを複製する必要はありません。説明するのは非常に複雑ですが、コードを4回繰り返すNEONには関心がありません。

void neon_asm_convert(uint8_t * __restrict dest, uint8_t * __restrict src, int numPixels)
{
  __asm__ volatile(
   "# build the three constants:  \n"
   "mov r4, #28                   \n" // Blue channel multiplier
   "mov r5, #151                  \n" // Green channel multiplier
   "mov r6, #77                   \n" // Red channel multiplier
   "vdup.8 d4, r4                 \n"
   "vdup.8 d5, r5                 \n"
   "vdup.8 d6, r6                 \n"

   "0: \n"
   "# load 8 pixels: \n"  //RGBR
   "vld3.8 {d0-d2}, [%1]! \n"
   "# do the weight average: \n"
   "vmull.u8 q7, d0, d4 \n"
   "vmlal.u8 q7, d1, d5 \n"
   "vmlal.u8 q7, d2, d6 \n"
   "# shift and store: \n"
   "vshrn.u16 d7, q7, #8 \n" // Divide q3 by 256 and store in the d7
   "vst1.8 {d7}, [%0]! \n"
   "subs %2, %2, #1 \n" // Decrement iteration count
   "bne 0b \n" // Repeat unil iteration count is not zero
   :
   : "r"(dest), "r"(src), "r"(numPixels)
   : "r4", "r5", "r6"
  );
}

動作するはずです。

于 2011-12-14T15:39:51.207 に答える
1

3つ(RGB)ではなく4つの値(RGBA)をロードします。

あなたはあなたの画像にありますが、あなたは連続したステップで等RGB RGB RGBをロードします。RGBR GBRG B...

"vld4.8 {d0-d3}, [%1]! \n"

代わりにあなたはすべきです

"vld3.8 {d0-d2}, [%1]! \n"

asmが正しいかどうかはわかりませんが、ここに間違いがあることに注意してください。また、ピクセルをメモリに戻すときに同じ間違いがないか確認してください

于 2011-12-14T09:34:56.593 に答える