记一次有趣的DirectX11程序闪屏的Debug过程

之前我做的DirectX11引擎发现有一个奇怪的问题:集显不会产生任何问题,而独显却发生了画面一闪一闪。这个问题以前没有出现,是在实现了脏矩形算法之后才出现的。而且闪屏的现象也是很奇怪,经过仔细发现后,应该是每次draw之前并没有保留下之前的画面,导致一个缓冲区有大量的黑色区域。但是我在代码中并没有清除RenderTargetView呀,而且为什么偏偏发生在独显,集显反而没事了呢?
于是我接下来,开始思考怎么把前台缓冲区的内容复制到后台缓冲区,也在GameDev向外国程序员请教,连续Debug了好几个小时,搞得精疲力尽后……终于忍不住去睡觉了。(我通常都是有Bug没解决的时候我都不想入睡,直到hold不住了才去睡觉。不知道是不是程序员的通病?)
醒来之后,好好看看DirectX11的教程吧,反正几个月后有好些内容都忘记了,温故而知新一下。结果在看教程的时候,看到交换链的时候,发现交换链有一个属性SwapEffect,以前都没有注意过。一查官方文档,原来是用于交换缓冲区的时候决定具体如何进行交换。结果仔细看文档,发现:

  • DXGI_SWAP_EFFECT_DISCARD
    Use this flag to specify the bit-block transfer (bitblt) model and to specify that DXGI discard the contents of the back buffer after you call IDXGISwapChain1::Present1. This flag is valid for a swap chain with more than one back buffer, although, applications only have read and write access to buffer 0. Use this flag to enable the display driver to select the most efficient presentation technique for the swap chain.

上面被我加粗那句,让我大吃一惊,原来这个标记会让显卡选择最高效的交换技术。这不就是导致不同显卡出现不同交换效果的原因吗?我查了一下自己的程序中自己交换链并没有设置该属性,结果默认为DXGI_SWAP_EFFECT_DISCARD,我猜测是集显能力不够没有进行抛弃后备缓冲区,而独显能力强大才可能进行了抛弃后备缓冲区,独显甚至也可能没有进行bitblt而是用flip来交换。
后来我就怎么解决了呢,就在创建交换链的时候加了一句:

swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_SEQUENTIAL;

如此轻松地解决掉这个Bug了。
为什么之前连续想了好几个小时都没想到是交换链的属性出了问题呢?
可见,睡眠不足会影响Debug的分析推理能力。发现Bug之后,最好的解决办法可能是大睡一觉。

你可能感兴趣的:(1.,随想录,一,DirectX11)