◎平均ルーチン(50%固定αブレンディング) ピクセルフォーマットは15bpp(R5G5B5)とします。 スプライトパターンとフレームバッファのRGB値それぞれの平均をとります。 /* C言語風表記(1ピクセル処理) */ /* vram = フレームバッファへのポインタ */ /* sprite = スプライトパターンへのポインタ */ *vram = (*vram & *sprite) + (((*vram ^ *sprite) & 0x7bde) >> 1); ; NASM(8ピクセル処理) ;UV大文字表記は他のパイプに移動できない命令です ;edi = フレームバッファのアドレス ;ebx = スプライトパターンのアドレス ;mm7 = 07bde7bde7bde7bdeh movq mm1,[ebx] ;U1 mm1 = *sprite ;v1 MMX命令のみ挿入可能 movq mm4,[ebx+8] ;U2 ;v2 MMX命令のみ挿入可能 movq mm0,[edi] ;U3 mm0 = *vram movq mm2,mm1 ;v3 mm2 = *sprite movq mm3,[edi+8] ;U4 movq mm5,mm4 ;v4 pxor mm1,mm0 ;u5 mm1 = *vram ^ *sprite pxor mm4,mm3 ;v5 pand mm1,mm7 ;u6 mm1 = (*vram ^ *sprite) & 0x7bde pand mm4,mm7 ;v6 psrlw mm1,1 ;u7 mm1 = ((*vram ^ *sprite) & 0x7bde) >> 1 pand mm0,mm2 ;v7 mm0 = *vram & *sprite psrlw mm4,1 ;u8 pand mm3,mm5 ;v8 lea edi,[edi+16] ;u9 パイプが空いたので入れてみる paddw mm0,mm1 ;v9 mm0 = (*vram & *sprite) + (((*vram ^ ... lea ebx,[ebx+16] ;u10 パイプが空いたので入れてみる paddw mm3,mm4 ;v10 movq [edi-16],mm0 ;U11<-9 ;v11 MMX命令のみ挿入可能 movq [edi-8],mm3 ;U12<-10 有効なペアリングのために4ピクセルのデーターを2組処理しています。 とりあえずキャッシュが全てヒットした場合を考えます。 MMX Pentium(P55C)では、 8ピクセル当たり12クロックで処理します。 パターンをQWORDにアラインするのは当然にしても、 転送先のアドレスは表示位置によって変わってしまうので、 8ピクセル当たり24クロック程度と考えるのが妥当です。 これらの値は実際に測定し確認しました。
; NASM整数命令版(2ピクセル処理) ;UV大文字表記は他のパイプに移動できない命令です ;edi = フレームバッファのアドレス ;ebx = スプライトパターンのアドレス mov edx,[edi] ;u1 edx = *sprite mov eax,[ebx] ;v1 eax = *vram mov esi,edx ;u2 esi = *sprite xor edx,eax ;v2 edx = *vram ^ *sprite lea edi,[edi+4] ;u3 and edx,07bde7bdeh ;v3 edx = (*vram ^ *sprite) & 0x7bde shr edx,1 ;U4 edx = ((*vram ^ *sprite) & 0x7bde) >> 1 and eax,esi ;v4 eax = *vram & *sprite add eax,edx ;u5 eax = (*vram & *sprite) + (((*vram ^ ... lea ebx,[ebx+4] ;v5 mov [edi-4],eax ;u6 Pentium や MMX Pentium(P55C)では、 2ピクセル当たり6クロックで処理します。 パターンをDWORDにアラインするのは当然にしても、 転送先のアドレスは表示位置によって変わってしまうので、 2ピクセル当たり12クロック程度と考えるのが妥当です。 これらの値は実際に測定し確認しました。