首页
社区
课程
招聘
[原创]N卡全局设置之垂直同步覆盖的实现
发表于: 2014-7-19 02:20 17183

[原创]N卡全局设置之垂直同步覆盖的实现

2014-7-19 02:20
17183

作者:hhstudy
博客: http://hi.baidu.com/hhstudy
转载请在文章开头注明出处

垂直同步是vertical synchronization的简称。基本思路是将显示器的刷新周期和显卡输出画面的周期同步起来,其目的是为了避免一种称之为“画面撕裂”的现象。顾名思义,“画面撕裂”其实就是画面移动较快的时候,画面看上去是两截,上面半副图和下面半副图就像是两张相差不多的图的各自半部分拼凑起来的一样。这现象恐怕打游戏的都见过。垂直同步的原理和“画面撕裂”的原因请自行谷歌。
下面主要研究某卡驱动是如何猥琐的实现强制覆盖应用程序的垂直同步设置。以及自己实现一个覆盖应用程序垂直同步设置的程序。
    环境配置
    OS win8.1_x86 显卡 Nvidia GTX 660

在UserMode中,垂直同步至少可以在2个地方设置(其实一般也就这两个地方了)。
1.由程序发起调用 ,程序在CreateDevice 的时候指定pPresentationParameters->PresentationInterval = D3DPRESENT_INTERVAL_ONE(TWO,THREE,FOUR也可以) 参数即可。

HRESULT CreateDevice(   
  [in]           UINT Adapter,
  [in]           D3DDEVTYPE DeviceType,
  [in]           HWND hFocusWindow,
  [in]           DWORD BehaviorFlags,
  [in, out]      D3DPRESENT_PARAMETERS *pPresentationParameters,
  [out, retval]  IDirect3DDevice9 **ppReturnedDeviceInterface
);
PFND3DDDI_PRESENTCB pfnPresentCb
__checkReturn HRESULT APIENTRY CALLBACK pfnPresentCb(
  _In_  HANDLE hDevice,
  _In_  const D3DDDICB_PRESENT *pData
);
ChildEBP RetAddr  Args to Child              
bffe7b90 8c6422d9 8110d858 bffe7cd0 bffe7c8c dxgkrnl!DXGCONTEXT::Present (FPO: [Non-Fpo])
bffe7d38 92350ea0 00000000 c1dc1db8 bffe7d54 dxgkrnl!DxgkPresent+0x24d (FPO: [Non-Fpo])
bffe7d48 81d1b377 00fbb170 0394f3f8 778b2da4 win32k!NtGdiDdDDIPresent+0x14 (FPO: [1,0,0])
bffe7d48 778b2da4 00fbb170 0394f3f8 778b2da4 nt!KiSystemServicePostCall (FPO: [0,3] TrapFrame @ bffe7d54)
0394f130 76896bdc 70747363 00fbb170 00fbb170 ntdll!KiFastSystemCallRet (FPO: [0,0,0])
0394f134 70747363 00fbb170 00fbb170 0587d000 GDI32!NtGdiDdDDIPresent+0xa (FPO: [1,0,0])
0394f3f8 53134e24 00fbb0b0 0394f540 00fbb170 d3d9!PresentCB+0xe2 (FPO: [2,171,4])
WARNING: Stack unwind information not available. Following frames may be wrong.
0394f424 53134b58 0394f540 00000000 0587d000 nvd3dum!QueryOglResource+0x21b84
0394f46c 53134d1b 0394f540 0587d000 025b5140 nvd3dum!QueryOglResource+0x218b8
0394f484 531079ab 0394f540 00000504 0587d000 nvd3dum!QueryOglResource+0x21a7b
0394f760 531094db 00000504 036c9040 03789818 nvd3dum+0x6979ab
0394f778 70870b2a 0587d000 03789818 00000001 nvd3dum+0x6994db
0394f7a0 70871665 03789314 00000001 00000000 d3d9!CBatchFilterI::ProcessBatch+0x4c2 (FPO: [2,3,4])
0394f7b8 70870472 0394f7cc 76ae17ad 036c9040 d3d9!CBatchFilterI::WorkerThread+0x2d (FPO: [0,0,4])
0394f7c0 76ae17ad 036c9040 0394f810 77893af4 d3d9!CBatchFilterI::LHBatchWorkerThread+0xd (FPO: [1,0,0])
0394f7cc 77893af4 036c9040 2cb22ace 00000000 KERNEL32!BaseThreadInitThunk+0xe (FPO: [1,0,0])
0394f810 77893acd ffffffff 778c42a6 00000000 ntdll!__RtlUserThreadStart+0x20 (FPO: [Non-Fpo])
0394f820 00000000 70870465 036c9040 00000000 ntdll!_RtlUserThreadStart+0x1b (FPO: [2,2,0])
NTSTATUS APIENTRY D3DKMTPresent(
  _In_  const D3DKMT_PRESENT *pData
);
typedef struct _D3DKMT_PRESENT {
  union {
    D3DKMT_HANDLE hDevice;
    D3DKMT_HANDLE hContext;
  };
  HWND                           hWindow;
  D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId;
  D3DKMT_HANDLE                  hSource;
  D3DKMT_HANDLE                  hDestination;
  UINT                           Color;
  RECT                           DstRect;
  RECT                           SrcRect;
  UINT                           SubRectCnt;
  const RECT                     *pSrcSubRects;
  UINT                           PresentCount;
  D3DDDI_FLIPINTERVAL_TYPE       FlipInterval;
  D3DKMT_PRESENTFLAGS            Flags;
  ULONG                          BroadcastContextCount;
  D3DKMT_HANDLE                  BroadcastContext[D3DDDI_MAX_BROADCAST_CONTEXT];
  HANDLE                         PresentLimitSemaphore;
  D3DKMT_PRESENTHISTORYTOKEN     PresentHistoryToken;
#if (DXGKDDI_INTERFACE_VERSION >= DXGKDDI_INTERFACE_VERSION_WIN8)
  D3DKMT_PRESENT_RGNS            *pPresentRegions;
#endif 
} D3DKMT_PRESENT;
1: kd> dd 00fbb170 
00fbb170  800014c0 00500442 00000000 40002840
00fbb180  00000000 00000000 00000000 00000000
00fbb190  00000000 00000000 00000000 00000000
00fbb1a0  00000000 00000000 00000001 00000000
00fbb1b0  00097f37 00000000 00001004 00000000
00fbb1c0  00000000 00000000 00000000 00000000
00fbb1d0  00000000 00000000 00000000 00000000
00fbb1e0  00000000 00000000 00000000 00000000

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 3
支持
分享
最新回复 (9)
雪    币: 2664
活跃值: (3401)
能力值: ( LV13,RANK:1760 )
在线值:
发帖
回帖
粉丝
2
写的挺好,没人坐沙发,偶来坐...
2014-7-19 11:01
0
雪    币: 47147
活跃值: (20465)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
3
hhstudy对N卡蛮熟悉的,可以用这个来做些东西。
2014-7-19 11:23
0
雪    币: 244
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
这是我第一次看见论坛有人发这方面这么给力的帖子O(∩_∩)O~
2014-7-19 11:33
0
雪    币: 144
活跃值: (48)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
mark
2014-7-19 11:43
0
雪    币: 35
活跃值: (20)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
这个牛啊
2014-7-19 21:53
0
雪    币: 65
活跃值: (452)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
7
我了解比较粗浅,这个是API级别的,等有时间了 ,再搞一个帖子来写Runtime 是怎么实现垂直同步的。
2014-7-20 00:30
0
雪    币: 2161
活跃值: (750)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
8
怪不得看有些人发的帖子中fps都好几百,普通显卡的刷新率也就是60,原来是垂直同步的原因。
2014-7-20 07:33
0
雪    币: 627
活跃值: (663)
能力值: ( LV9,RANK:270 )
在线值:
发帖
回帖
粉丝
9
学习学习。
2014-7-20 10:37
0
雪    币: 297
活跃值: (265)
能力值: ( LV4,RANK:55 )
在线值:
发帖
回帖
粉丝
10
mark谢谢分享
2014-7-21 08:20
0
游客
登录 | 注册 方可回帖
返回
//