从IDXGIOutput.GetDisplayModeList返回的DXGI_MODE_SCALING_UNSPECIFIED缩放模式在模式列表中的含义是什么?

时间:2015-03-17 07:45:31

标签: windows fullscreen direct3d dxgi

我试图创建支持全屏模式的Direct3D 10/11应用程序。为此,我必须向用户提供可用的视频模式列表。此外,将当前桌面设置选为默认视频模式以便最大限度地减少视频模式更改将会很棒。

在Direct3D 9中执行它非常简单。例如,这是我的模式列表,由Direct3D 9提供:

Current mode: 1920x1080x60Hz 32bit X8R8G8B8
Available modes:
Front buffer format 32bit X8R8G8B8: 35
1: 1920x1080x60Hz
2: 640x480x60Hz
3: 640x480x72Hz
4: 640x480x75Hz
5: 720x480x56Hz
6: 720x480x60Hz
7: 720x480x72Hz
8: 720x480x75Hz
9: 720x576x56Hz
10: 720x576x60Hz
11: 720x576x72Hz
12: 720x576x75Hz
13: 800x600x56Hz
14: 800x600x60Hz
15: 800x600x72Hz
16: 800x600x75Hz
17: 1024x768x60Hz
18: 1024x768x70Hz
19: 1024x768x75Hz
20: 1152x864x75Hz
21: 1280x720x60Hz
22: 1280x768x60Hz
23: 1280x800x60Hz
24: 1280x960x60Hz
25: 1280x1024x60Hz
26: 1280x1024x75Hz
27: 1360x768x60Hz
28: 1366x768x60Hz
29: 1600x900x59Hz
30: 1600x900x60Hz
31: 1600x1024x59Hz
32: 1600x1024x60Hz
33: 1680x1050x59Hz
34: 1680x1050x60Hz
35: 1440x900x60Hz

但是通过DXGI做同样简单的事情有点复杂。令我困惑的是, IDXGIOutpit.GetDisplayModeList 方法最多返回3个相同视频模式的副本。不同之处在于提供的缩放模式:

DXGI_MODE_SCALING_UNSPECIFIED = 0
DXGI_MODE_SCALING_CENTERED = 1
DXGI_MODE_SCALING_STRETCHED = 2

这是:

List of modes for format 32bit R8G8B8A8 UNorm:
640x480x60Hz Progressive Unspecified 
640x480x72Hz Progressive Unspecified 
640x480x75Hz Progressive Unspecified 
720x480x56Hz Progressive Unspecified 
720x480x56Hz Progressive Centered 
720x480x56Hz Progressive Stretched 
720x480x60Hz Progressive Unspecified 
720x480x60Hz Progressive Centered 
720x480x60Hz Progressive Stretched 
720x480x72Hz Progressive Unspecified 
720x480x72Hz Progressive Centered 
720x480x72Hz Progressive Stretched 
720x480x75Hz Progressive Unspecified 
720x480x75Hz Progressive Centered 
720x480x75Hz Progressive Stretched 
720x576x56Hz Progressive Unspecified 
720x576x56Hz Progressive Centered 
720x576x56Hz Progressive Stretched 
720x576x60Hz Progressive Unspecified 
720x576x60Hz Progressive Centered 
720x576x60Hz Progressive Stretched 
720x576x72Hz Progressive Unspecified 
720x576x72Hz Progressive Centered 
720x576x72Hz Progressive Stretched 
720x576x75Hz Progressive Unspecified 
720x576x75Hz Progressive Centered 
720x576x75Hz Progressive Stretched 
800x600x56Hz Progressive Unspecified 
800x600x60Hz Progressive Unspecified 
800x600x72Hz Progressive Unspecified 
800x600x75Hz Progressive Unspecified 
1024x768x60Hz Progressive Unspecified 
1024x768x70Hz Progressive Unspecified 
1024x768x75Hz Progressive Unspecified 
1152x864x75Hz Progressive Unspecified 
1280x720x60Hz Progressive Unspecified 
1280x768x59Hz Progressive Unspecified 
1280x768x59Hz Progressive Centered 
1280x768x59Hz Progressive Stretched 
1280x800x59Hz Progressive Unspecified 
1280x960x60Hz Progressive Unspecified 
1280x1024x60Hz Progressive Unspecified 
1280x1024x75Hz Progressive Unspecified 
1360x768x59Hz Progressive Unspecified 
1360x768x59Hz Progressive Centered 
1360x768x59Hz Progressive Stretched 
1366x768x59Hz Progressive Unspecified 
1366x768x59Hz Progressive Centered 
1366x768x59Hz Progressive Stretched 
1440x900x59Hz Progressive Unspecified 
1600x900x59Hz Progressive Unspecified 
1600x900x59Hz Progressive Centered 
1600x900x59Hz Progressive Stretched 
1600x1024x59Hz Progressive Unspecified 
1600x1024x59Hz Progressive Centered 
1600x1024x59Hz Progressive Stretched 
1680x1050x59Hz Progressive Unspecified 
1920x1080x60Hz Progressive Unspecified 

首先我想,DXGI_MODE_SCALING_STRETCHED =这种模式需要拉伸(后缓冲区较小,然后前一个,分辨率可能不是物理),DXGI_MODE_SCALING_CENTERED =在此模式下图像可能不占用整个屏幕(后台缓冲区较小,则前一个,但保留了物理分辨率),DXGI_MODE_SCALING_UNSPECIFIED ="正常模式" (背面和前面缓冲区的大小匹配,但不保证物理分辨率)。即我应该只列出那些具有Scaling = DXGI_MODE_SCALING_UNSPECIFIED的模式。

但后来我试着确定当前的模式。根据MSDN,当使用 IDXGIOutput.FindClosestMatchingMode 方法时,如果您没有指定其中一个参数,则此方法会倾向于当前桌面设置,优先化参数,设置并使用某种排序优先级(ScanlineOrdering> Scaling> Format> Resolution> RefreshRate)来选择其他的。所以我创建了设备(为了能够将格式指定为DXGI_FORMAT_UNKNOWN)并将完全未确定的模式传递给此方法(包括Scaling = DXGI_MODE_SCALING_UNSPECIFIED)。

结果如下:

Suggested mode: 32bit B8G8R8A8 UNorm 1600x1024x59Hz Progressive Stretched 
Suggested mode 1.1: 32bit B8G8R8A8 UNorm 1600x1024x59Hz Progressive Stretched Mono

如您所见,它与当前桌面模式(1920x1080x60Hz)不匹配。我尝试将当前的桌面模式更改为不同的模式并发现 IDXGIOutput.FindClosestMatchingMode 倾向于选择最接近桌面参数的最近可用模式,但使用Scaling = DXGI_MODE_SCALING_STRETCHED ,只是忽略我指定的Scaling = DXGI_MODE_SCALING_UNSPECIFIED。

Current mode: 32bit B8G8R8A8 UNorm 1024x768x75Hz Progressive Unspecified
Suggested mode: 32bit B8G8R8A8 UNorm 1280x768x59Hz Progressive Stretched 
Suggested mode 1.1: 32bit B8G8R8A8 UNorm 1280x768x59Hz Progressive Stretched Mono 

这让我得出了一个惊人的结论,DXGI_MODE_SCALING_UNSPECIFIED被视为Scaling参数的无效值,至少对于 IDXGIFactory.CreateSwapChain 方法(否则为什么 IDXGIOutput.FindClosestMatchingMode ,用于选择模式,在大多数情况下将提供给 IDXGIFactory.CreateSwapChain ,拒绝选择1920x1080x60Hz?)。

我想 IDXGIFactory.CreateSwapChain 甚至在内部调用 IDXGIOutput.FindClosestMatchingMode 来确定哪个"物理"使用模式。但那么......这是什么意思?我无法提供模式,没有Scaling = DXGI_MODE_SCALING_CENTERED或DXGI_MODE_SCALING_STRETCHED给用户,因为这些模式不是"物理"那些 - 即 IDXGIFactory.CreateSwapChain 会选择其他模式吗?

但是为什么在可用模式列表中返回DXGI_MODE_SCALING_UNSPECIFIED?如果仅在调用 IDXGIFactory.CreateSwapChain 方法时使用Scaling参数来指定我是想要居中图像还是缩放它,如果提供的模式不匹配任何" physical"一,在调用 IDXGISwapChain.ResizeTarget 时未使用,因为这种方法需要" physical"仅模式,那么为什么缩放参数混合在一个列表中,由 IDXGIOutpit.GetDisplayModeList 返回?

我应该向用户显示哪些模式?只有那些有Scaling<>的人DXGI_MODE_SCALING_UNSPECIFIED?或者我应该做相反的事情?如何通过DXGI本身确定当前模式,而不是使用传统的Win API?

任何人都可以向我解释一下吗? Cuz在MSDN中没有任何澄清。

1 个答案:

答案 0 :(得分:1)

这个问题已经吹了我的大脑很长一段时间,但突然间,当我决定向别人询问这个问题时,我得到了一个见解并自己回答了我的问题。我最初的假设是正确的 - 问题在于DXGI或我的视频卡驱动程序的奇怪行为。

问题实际上是,由于某些未知原因,DXGI或我的视频驱动程序始终将我当前的桌面模式视为DXGI_MODE_SCALING_STRETCHED而不是DXGI_MODE_SCALING_UNSPECIFIED。这是所有问题的根源,因为当它们倾向于当前的桌面模式时#34;实现,事实上,模式被Scaling参数拳击过滤,导致可怕的结果。

这就是:

我当前的桌面模式是

32bit B8G8R8A8 UNorm 1920x1080x60Hz Progressive Stretched (instead of Unspecified)

IDXGIOutput.FindClosestMatchingMode 尝试查找最接近它的模式,但首先按缩放模式进行过滤。事实上,问题是没有1920x1080x60Hz模式,Scaling = DXGI_MODE_SCALING_STRETCHED。这就是为什么它不是选择1920x1080x60Hz而是选择最接近模式的DXGI_MODE_SCALING_STRETCHED,即1600x1024x59Hz。