我在 Directx 9 应用程序中实现延迟着色。我的延迟着色方法需要 3 个渲染目标(颜色、位置和正常)。有必要:
- 在“渲染”函数的开头设置设备中的渲染目标
- 在“rt pass”中将数据绘制给他们
- 从设备中删除渲染目标(以免在后续通道中绘制它们)
- 将渲染目标设置为后续通道的纹理,以便效果可以将“绘制”的数据调用到“rt通道”中的 rt...
此方法工作正常,但是,我遇到了性能问题。我将它们缩小到两个函数调用:
IDirect3DTexture9::GetSurfaceLevel()
IDirect3DDevice9::SetRenderTarget()
这是设置渲染目标的代码:
IDirect3DDevice9 *pd3dDevice = CEffectManager::GetDevice();
IDirect3DTexture9 *pRT = CEffectManager::GetColorRT();
IDirect3DSurface9 *pSrf = NULL;
pRT->GetSurfaceLevel( 0, &pSrf );
pd3dDevice->SetRenderTarget( 0, pSrf );
PIX 表明调用 GetSurfaceLevel() 的持续时间(周期)非常高,每次调用约 1/2 毫秒(持续时间 / 总持续时间 * 1 / 帧速率)。因为要得到3个面,加起来,持续时间太长了!它比组合的绘制调用大 4 倍以上......
我试图通过在渲染目标创建期间存储指向表面的指针来消除对 GetSurfaceLevel() 的调用......奇怪的是,SetRenderTarget() 函数假定了相同的持续时间(在它的持续时间可以忽略不计之前)。这是修改后的代码:
IDirect3DDevice9 *pd3dDevice = CEffectManager::GetDevice();
IDirect3DSurface9 *pSrf = CEffectManager::GetColorSurface();
pd3dDevice->SetRenderTarget( 0, pSrf );
有没有办法解决这个性能问题?为什么第二种方法和第一种方法一样长?似乎 IDirect3DDevice9::SetRenderTarget() 中的过程只需要时间......我可以设置一个设备状态来帮助提高性能吗?
更新:为了更好地测试性能,我实现了以下代码:
IDirect3DDevice9 *pd3dDevice = CEffectManager::GetDevice();
IDirect3DTexture9 *pRT = CEffectManager::GetColorRT();
IDirect3DSurface9 *pSRF = NULL;
IDirect3DQuery9 *pEvent = NULL;
LARG_INTEGER lnStart, lnStop, lnFrequency;
// create query
pd3dDevice->CreateQuery( D3DQUERYTYPE_EVENT, &pEvent );
// insert 'end' marker
pEvent->Issue( D3DISSUE_END );
// flush command buffer
while( S_FALSE == pEvent->GetData( NULL, 0, D3DGETDATA_FLUSH ) );
// get start time
QueryPerformanceCounter( &lnStart );
// api call
pRT->GetSurfaceLevel();
// insert 'end' marker
pEvent->Issue( D3DISSUE_END )
// flush the command buffer
while( S_FALSE == pEvent->GetData( NULL, 0, D3DGETDATA_FLUSH ) );
QueryPerformanceCounter( &lnStop );
QueryPerformanceFrequency( &lnFreq );
lnStop.QuadPart -= lnStart.QuadPart;
float fElapsedTime = ( float )lnStop.QuadPart / ( float )lnFreq.QuadPart;
fElapsedTime 平均测量为 10 - 50 微秒我在 IDirect3DDevice9::SetRenderTarget() 上执行了相同的测试,结果平均测量为 5 - 30 微秒......
这个数据比我从 PIX 得到的要好得多……这表明延迟没有我想象的那么大,但是,使用延迟着色会大大降低帧速率……这似乎是最有可能的来源由于性能损失...我是否有效地查询了设备?