◎平均ルーチン(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クロック程度と考えるのが妥当です。
これらの値は実際に測定し確認しました。