功能摘要 (适用于 Windows Vista 的 Direct3D 9)

本文档专门介绍用于 DirectX 图形的 Windows Vista 扩展功能。 若要开发 DirectX for Windows Vista 的强大功能,必须安装 Windows Vista SDK 以及 DirectX SDK。 使用 DirectX for Windows Vista 的应用程序必须使用使用 WDDM 驱动程序(Windows 设备驱动程序模型)而不是 XPDM(XP 驱动程序模型)的硬件;未实现 WDDM 的驱动程序无法实例化 Windows Vista DirectX 图形接口。

在以下部分之一中发现 Windows Vista 中的新 DirectX 图形功能:

设备行为变化

设备现在仅在两种情况下会丢失:一是当硬件因挂起而被重置时,二是当停止设备驱动程序时。 当硬件挂起时,可以通过调用 ResetEx 来重置设备。 如果硬件挂起,将丢失纹理内存。

停止驱动程序后,必须重新创建 IDirect9Ex 对象才能恢复呈现。

当演示区域被窗口模式中的另一个窗口遮盖,或者当全屏应用程序最小化时,PresentEx 将返回S_D3DPRESENTATIONOCCLUDED。 在收到 WM_ACTIVATEAPP 回调消息后,全屏应用程序可以恢复呈现。

在早期版本的 DirectX 中,当应用程序遇到模式更改时,恢复的唯一方法是重置设备并重新创建所有视频内存资源和交换链。 现在使用 DirectX for Windows Vista 时,在模式更改后调用“重置”不会导致纹理内存图面、纹理和状态信息丢失,并且无需重新创建这些资源。

禁用多线程软件顶点处理

添加了新的上限位 (D3DCREATE_DISABLE_PSGP_THREADING),这将为软件顶点处理 (swvp) 禁用多线程处理。 使用此宏为 IDirect3D9::CreateDevice 生成行为标志。

#define D3DCREATE_DISABLE_PSGP_THREADING

一位表面

有一种新的一位表面格式类型,在处理文本字形时非常有用。 新格式称为D3DFMT_A1。 一位表面被设计为可用作每像素纹理,或 ComposeRects 或 ColorFill 生成的渲染目标输出。 表面的宽度和高度没有单独的上限;实现必须支持一个大小为 2K 纹素 x 8K 纹素的表面。

一位表面的每个纹素都有一位;因此,一表示像素的所有组成部分 (r,g,b,a) 均为 1,零表示所有组成部分都等于 0。 可以将一位表面与以下 API 配合使用:ColorFill、UpdateSurface 和 UpdateTexture。

读取一位表面时,运行时可以执行点样本或卷积筛选。 卷积筛选器是可调整的(请参阅 SetConvolutionMonoKernel)。

一位表面存在一些限制:

  • Mip 映射不受支持
  • sRGB 数据无法读取或写入到一位表面。
  • 单比特表面不能用作顶点纹理或多重抽样。

读取深度/模具缓冲区

使用 IDirect3DDevice9::UpdateSurface 从通过 IDirect3DDevice9::CreateDepthStencilSurface 或 IDirect3DDevice9::GetDepthStencilSurface 获得的表面中读取或写入深度/模具数据。

首先,使用 IDirect3DDevice9::CreateOffscreenPlainSurface 创建一个可锁定的仅深度或仅模具表面。 使用以下格式之一:

  • D3DFMT_D16_LOCKABLE
  • D3DFMT_D32F_LOCKABLE
  • D3DFMT_D32_LOCKABLE
  • D3DFMT_S8_LOCKABLE

其次,在深度/模具缓冲区和新创建的可锁定深度或模具表面之间传输数据。 传输是使用 IDirect3DDevice9::UpdateSurface 执行的。

当两个表面都是 LOCKABLE 格式或两个表面都不可锁定时,UpdateSurface 将失败。

传输不存在的数据将导致出现错误(例如,从不可锁定的仅深度表面传输到 D3DFMT_S8_LOCKABLE 表面)。

IDirect3DDevice9::UpdateSurface 的其余限制仍适用。

共享资源

现在可以在设备或进程之间共享 Direct3D 资源。 这适用于任何 Direct3D 资源,包括纹理、顶点缓冲区、索引缓冲区或表面(例如渲染目标、深度模板缓冲区或离屏普通表面)。 若要共享,需要在创建时指定用于共享的资源,并在默认池(D3DPOOL_DEFAULT)中找到资源。 创建资源以供共享后,可以在进程内的设备之间共享资源,也可以跨进程共享。

若要启用共享资源,资源创建 API 具有额外的句柄参数。 这是指向共享资源的 HANDLE。 在 DirectX 以前的修订中,此参数是 API 签名的一部分,但未被使用,并且必须设置为 NULL。 从 Windows Vista 开始,使用以下方式使用 pSharedHandle:

  • 将指针(pSharedHandle)设置为 NULL 以便不共享资源。 这就像在 Windows Vista 之前 DirectX 的行为一样。
  • 若要创建共享资源,请使用未初始化的句柄调用任何资源创建 API(指针本身不是 NULL (pSharedHandle != NULL),但指针指向 NULL 值(*pSharedHandle == NULL))。 API 将生成共享资源并返回有效的句柄。
  • 若要使用非NULL 共享资源句柄打开和访问以前创建的共享资源,请将 pSharedHandle 设置为该句柄的地址。 以这种方式打开以前创建的共享资源后,可以使用 Direct3D 9 或 Direct3D 9Ex API 中返回的接口,就像接口是该类型的典型资源一样。

资源创建 API 包括 - CreateTextureCreateVolumeTextureCreateCubeTextureCreateRenderTargetCreateVertexBufferCreateIndexBufferCreateDepthStencilSurfaceCreateOffscreenPlainSurfaceCreateDepthStencilSurfaceExCreateOffscreenPlainSurfaceExCreateRenderTargetEx

使用共享资源存在一些限制。 其中包括:

  • 用于打开共享资源的 API 必须与用于创建共享资源的 API 匹配。 例如,如果使用 CreateTexture 创建共享资源,则必须使用 CreateTexture 打开该共享资源;如果使用 CreateRenderTarget 创建共享资源,则必须使用 CreateRenderTarget 打开该共享资源;等等。
  • 打开共享资源时,必须指定D3DPOOL_DEFAULT。
  • 可锁定的资源(例如,具有D3DUSAGE_DYNAMIC、顶点缓冲区和索引缓冲区的纹理)在共享时可能会遇到性能不佳的问题。 在某些硬件上,可锁定的渲染目标将无法被共享。
  • 对跨进程共享资源的引用必须具有与原始资源相同的维度。 跨进程传递句柄时,请包含维度信息,以便可以一致地创建引用。
  • 共享跨进程界面没有同步机制。 在预期情况下,共享表面的读取/写入更改可能不会反映在引用进程的表面视图中。 若要提供同步,请使用事件查询或锁定纹理。
  • 只有最初创建共享资源的进程才能锁定它(打开对该共享资源的引用的任何进程都无法锁定它)。
  • 如果共享资源已锁定,则无法验证其他进程是否可用。

在进行混合之前进行 sRGB 转换

现在可以检查设备是否可以在帧缓冲区混合之前将管道数据转换为 sRGB。 这意味着设备将渲染目标的值从 sRGB 色域转换。 若要查看硬件是否支持转换,请检查此上限:

D3DPMISCCAPS_POSTBLENDSRGBCONVERT

此上限识别支持在混合之前支持转换为 sRGB 的硬件。 此功能对于桌面窗口管理器 (DWM) 中 fp16 帧缓冲区的高质量呈现非常重要。

StretchRect 改进

在早期版本的 DirectX 中,StretchRect 有许多限制来容纳不同的驱动程序(请参阅 IDirect3DDevice9::StretchRect)。 Windows Vista 基于 Windows 设备驱动程序模型(WDDM)构建。 这种新的驱动程序模型更可靠,并且允许驱动程序在硬件中处理特殊情况。

通常,仅剩的限制是,必须使用呈现目标用法 (D3DUSAGE_RENDERTARGET) 创建呈现目标。 如果执行简单复制(源和 dest 的格式相同、大小相同且没有子矩形),则会取消此限制。

在系统内存中创建纹理

对系统内存的使用、分配和删除具有更多灵活性的应用程序现在可以从系统内存指针创建纹理。 例如,应用程序可以从 GDI 系统内存位图指针创建 Direct3D 纹理。

需要执行两项操作来创建这样的纹理:

  • 分配足够的系统内存来保存纹理图面。 最小字节数是每个像素的宽度 x 高度 x 字节。
  • 将 HANDLE* 参数的系统内存表面的指针地址传递给 IDirect3DDevice9::CreateTexture。

下面是 IDirect3DDevice9::CreateTexture 的函数原型:

STDMETHOD(CreateTexture)(THIS_ UINT Width, UINT Height, UINT Levels, 
    DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DTexture9** ppTexture, 
    HANDLE* pSharedHandle)

系统内存纹理具有以下限制:

  • 纹理间距必须等于纹理宽度乘以每个像素的字节数。
  • 使用压缩格式(DXT 格式)时,应用程序负责分配正确的大小。
  • 仅支持具有单个 mipmap 级别的纹理。
  • 传递给 CreateTexture 函数的 Pool 参数的值必须是 D3DPOOL_SYSTEMMEM。
  • 此 API 将提供的内存包装在纹理中。 使用此内存完成之前,请勿取消分配。