游戏开发论坛

 找回密码
 立即注册
搜索
查看: 2297|回复: 8

郁闷,MMX加速都没用,高手帮忙看看吧

[复制链接]

4

主题

17

帖子

17

积分

新手上路

Rank: 1

积分
17
发表于 2006-11-7 18:44:00 | 显示全部楼层 |阅读模式
  我看《游戏编程指南》上说DirectDraw提供的带透明色的BltFast( )此时的工作效率不容乐观,于是就想着自己写个函数试试。
   暂时不考虑RLE压缩,至少使用MMX优化应该效率不会很低吧,可是结果证明自己的函数根本没有DirectDraw的效率高。
   程序贴出来,希望大家能给看看,问题出在哪了。检查部分去掉了,代码有点长。

void DDBltCKMMX(LPDIRECTDRAWSURFACE7 lpDDSDest, LPDIRECTDRAWSURFACE7 lpDDSSrc,
int iDestX, int iDestY, int iSrcX, int iSrcY, int W, int H)
{
DDSURFACEDESC2 ddsdSrc, ddsdDest;
RECT rcSrc, rcDest;
BYTE *lpbSrc, *lpbDest;
DWORD dwSrcQuad, dwDestQuad;
DWORD dwRemainder;
DWORD dwColorKey;
// 获取图像宽高
ddsdSrc.dwSize = sizeof(DDSURFACEDESC2);
ddsdSrc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
lpDDSSrc->GetSurfaceDesc(&ddsdSrc);
ddsdDest.dwSize = sizeof(DDSURFACEDESC2);
ddsdDest.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
lpDDSDest->GetSurfaceDesc(&ddsdDest);
DDGetColorKey(lpDDSSrc, &dwColorKey);
// 锁定页面
ddsdSrc.dwSize = sizeof(DDSURFACEDESC2);
ddsdDest.dwSize = sizeof(DDSURFACEDESC2);
MakeRect(&rcSrc, iSrcX, iSrcY, W, H);
MakeRect(&rcDest, iDestX, iDestY, W, H);
// EnterCriticalSection(&gDDrawCS);
if(lpDDSSrc->Lock(&rcSrc, &ddsdSrc, DDLOCK_READONLY | DDLOCK_WAIT, NULL) != DD_OK){
//LeaveCriticalSection(&gDDrawCS);
return;
}
if(lpDDSDest->Lock(&rcDest, &ddsdDest, DDLOCK_WAIT, NULL) != DD_OK){
lpDDSSrc->Unlock(&rcSrc);
//LeaveCriticalSection(&gDDrawCS);
return;
}
// LeaveCriticalSection(&gDDrawCS);
// 执行复制操作
lpbSrc = (BYTE*)ddsdSrc.lpSurface;
lpbDest = (BYTE*)ddsdDest.lpSurface;
switch(ScreenMode){
case RGBMODE_555: // 555, 565代码相同
case RGBMODE_565: // 一次执行4个点
dwSrcQuad = ddsdSrc.lPitch - (W << 1);
dwDestQuad = ddsdDest.lPitch - (W << 1);
dwColorKey = (dwColorKey << 16) | dwColorKey;
dwRemainder = W & 0x03;
W = ((W - dwRemainder) >> 2);
__asm{
mov esi, lpbSrc;
mov edi, lpbDest;
mov ebx,  dwColorKey;
movd mm0, ebx;
punpckldq mm0, mm0;// 关键色
mov eax, H;
loop_H16:   // 高循环
mov ecx, W;
mov edx, dwRemainder;
loop_W16:   // 宽循环
cmp ecx, 0;
jz  loop_W_R16;
movq mm1, [esi];
movq mm2, [edi];
movq mm3, mm1;// save original source pixels
pcmpeqw mm3, mm0;// pixels equal to color key are set to 0xffff
pand mm2, mm3;   // if not , 0x0000
pcmpeqw mm4, mm4;//mm4 设为全1
pandn mm3, mm4;// 关键色的点将为0
pand mm1, mm3; // 去除关键色
por mm2, mm1;
movq [edi], mm2;
add  esi, 8;
add  edi, 8;
dec  ecx;
jmp loop_W16;
loop_W_R16:
cmp edx, 0;
jz loop_W_End16;
mov cx, [esi];
cmp cx, bx;
jz  skip_16;
mov [edi], cx;
add esi, 2;
add edi, 2;
skip_16:
dec edx;
jmp loop_W_R16;
loop_W_End16:
add esi, dwSrcQuad;
add edi, dwDestQuad;
dec eax;
cmp eax, 0;
jnz  loop_H16;
emms;
}
break;
case RGBMODE_32: // 32位颜色模式, 一次执行2个点
dwSrcQuad = ddsdSrc.lPitch - (W << 2);
dwDestQuad = ddsdDest.lPitch - (W << 2);
dwRemainder = W & 0x01;
W = ((W - dwRemainder) >> 1);
lpbSrc = (BYTE*)ddsdSrc.lpSurface;
lpbDest = (BYTE*)ddsdDest.lpSurface;
__asm{
mov esi, lpbSrc;
mov edi, lpbDest;
mov ebx, dwColorKey;
movd mm0, ebx;
punpckldq mm0, mm0;
mov eax, H;
loop_H32:   // 高循环
mov ecx, W;
mov edx, dwRemainder;
loop_W32:   // 宽循环
cmp ecx, 0;
jz  loop_W_R32;
movq mm1, [esi];
movq mm2, [edi];
movq mm3, mm1;// save original source pixels
pcmpeqd mm3, mm0;// pixels equal to color key are set to 0xffffffff
pand mm2, mm3;   // if not , 0x0
pcmpeqw mm4, mm4;
pandn mm3, mm4;
pand mm1, mm3;
por mm2, mm1;
movq [edi], mm2;

add  esi, 8;
add  edi, 8;
dec  ecx;
jmp loop_W32;
loop_W_R32:
cmp edx, 0;
jz loop_W_End32;
movd mm0, DWORD PTR [esi];
movd DWORD PTR [edi], mm0;
add esi, 4;
add edi, 4;
loop_W_End32:
add esi, dwSrcQuad;
add edi, dwDestQuad;
dec eax;
cmp eax, 0;
jnz  loop_H32;
emms;
}
break;
}
// EnterCriticalSection(&gDDrawCS);
lpDDSSrc->Unlock(&rcSrc);
lpDDSDest->Unlock(&rcDest);
// LeaveCriticalSection(&gDDrawCS);
}

106

主题

743

帖子

745

积分

高级会员

Rank: 4

积分
745
QQ
发表于 2006-11-7 18:56:00 | 显示全部楼层

Re:郁闷,MMX加速都没用,高手帮忙看看吧

请问楼主:有一次我插入一段汇编语言,结果VC++6.0编译器就挂掉了,不知道什么原因,现在就不插入汇编语言了。

1367

主题

1993

帖子

2118

积分

金牌会员

Rank: 6Rank: 6

积分
2118
发表于 2006-11-7 20:00:00 | 显示全部楼层

Re:郁闷,MMX加速都没用,高手帮忙看看吧

?????????

4

主题

17

帖子

17

积分

新手上路

Rank: 1

积分
17
 楼主| 发表于 2006-11-7 20:03:00 | 显示全部楼层

Re:郁闷,MMX加速都没用,高手帮忙看看吧

      如果寄存器的值被破坏了,程序会出错,比如出栈÷如栈不匹配。不过还真没见过编译器挂掉的。

     又改了一下程序,       
将原来的4句改成了2句
pcmpeqw mm4, mm4;
pandn mm3, mm4;
pand mm1, mm3;
por mm2, mm1;
======》
pandn mm2, mm0;// reverse mm2, pixels equal to color key is reset
por mm1, mm2;
不过速度并没明显改变。

9

主题

688

帖子

688

积分

高级会员

Rank: 4

积分
688
发表于 2006-11-7 20:15:00 | 显示全部楼层

回复hwbnet

编译器挂掉,装sp6试试。

106

主题

743

帖子

745

积分

高级会员

Rank: 4

积分
745
QQ
发表于 2006-11-7 21:06:00 | 显示全部楼层

Re:郁闷,MMX加速都没用,高手帮忙看看吧

sp6是什么?新的版本么?

5

主题

686

帖子

697

积分

高级会员

Rank: 4

积分
697
QQ
发表于 2006-11-7 21:35:00 | 显示全部楼层

Re:郁闷,MMX加速都没用,高手帮忙看看吧

DDRAW不是硬件加速的么?

4

主题

17

帖子

17

积分

新手上路

Rank: 1

积分
17
 楼主| 发表于 2006-11-7 22:02:00 | 显示全部楼层

Re:郁闷,MMX加速都没用,高手帮忙看看吧

   是啊,效率比我用MMX写高的多了, 20张图640 X 480,透明色复制,自己的函数才15帧。
用BltFast是25帧。
   估计用BLE压缩后的会高一些吧。

0

主题

275

帖子

676

积分

高级会员

Rank: 4

积分
676
发表于 2006-11-10 11:29:00 | 显示全部楼层

Re:郁闷,MMX加速都没用,高手帮忙看看吧

如果要用 MMX就用自?У?D形格式
?e用DIRECTDRAWSURFACE
不然又把surface?在 v-ram
而且BackSurface也要?定在System memory

不然MMX只有?p速笑果
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2026-1-25 19:26

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表