使用调试层调试应用
建议使用 调试层 来调试应用,以确保它们没有错误和警告。 调试层可帮助你编写 Direct3D 代码。 此外,使用调试层时可以提高工作效率,因为可以立即查看混淆呈现错误甚至在其源出现黑屏的原因。 调试层提供多个问题的警告。 例如,调试层针对以下问题提供警告:
- 忘记设置纹理,但在像素着色器中读取纹理
- 输出深度,但没有深度模具状态绑定
- 纹理创建失败,出现 INVALIDARG
下面我们将讨论如何启用 调试层 ,以及一些可以使用调试层来防止的问题。
启用调试层
若要启用调试层,请在调用 D3D11CreateDevice 函数以创建呈现设备时,在 Flags 参数中指定D3D11_CREATE_DEVICE_DEBUG标志。 以下示例代码演示如何在 Microsoft Visual Studio 项目处于调试版本中时启用调试层:
UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
#if defined(_DEBUG)
// If the project is in a debug build, enable the debug layer.
creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif
// Define the ordering of feature levels that Direct3D attempts to create.
D3D_FEATURE_LEVEL featureLevels[] =
{
D3D_FEATURE_LEVEL_11_1,
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
D3D_FEATURE_LEVEL_9_3,
D3D_FEATURE_LEVEL_9_1
};
ComPtr<ID3D11Device> d3dDevice;
ComPtr<ID3D11DeviceContext> d3dDeviceContext;
DX::ThrowIfFailed(
D3D11CreateDevice(
nullptr, // specify nullptr to use the default adapter
D3D_DRIVER_TYPE_HARDWARE,
nullptr, // specify nullptr because D3D_DRIVER_TYPE_HARDWARE
// indicates that this function uses hardware
creationFlags, // optionally set debug and Direct2D compatibility flags
featureLevels,
ARRAYSIZE(featureLevels),
D3D11_SDK_VERSION, // always set this to D3D11_SDK_VERSION
&d3dDevice,
nullptr,
&d3dDeviceContext
)
);
使用调试层防止应用中的错误
如果滥用 Direct3D 11 API 或传递错误参数, 调试层 的调试输出将报告错误或警告。 然后,你可以更正错误。 接下来,我们将介绍一些可能导致未定义行为甚至操作系统崩溃的编码问题。 可以使用调试层来捕获和防止这些问题。
不要将 NULL 指针传递给 Map
如果将 NULL 传递给 ID3D11DeviceContext::Map 方法的 pResource 或 pMappedResource 参数,则 Map 的行为未定义。 如果创建了仅支持 核心层的设备, 则映射 参数无效可能会使操作系统崩溃。 如果创建了支持 调试层的设备,则调试输出将在此无效 的映射 调用上报告错误。
在源和目标资源中限制源框
在调用 ID3D11DeviceContext::CopySubresourceRegion 方法时,源框必须位于源资源内。 目标偏移量、 (x、y 和 z) 允许源框在写入目标资源时偏移,但源框的尺寸和偏移量必须在资源的大小范围内。 如果尝试在目标资源外部复制或指定大于源资源的源框, 则 CopySubresourceRegion 的行为未定义。 如果创建了支持 调试层的设备,则调试输出将在此无效 的 CopySubresourceRegion 调用上报告错误。 CopySubresourceRegion 的参数无效会导致未定义的行为,并可能导致不正确的呈现、剪辑、无副本甚至删除呈现设备。
请勿删除 DiscardResource 或 DiscardView
除非正确创建资源,否则运行时会删除对 ID3D11DeviceContext1::D iscardResource 或 ID3D11DeviceContext1::D iscardView 的调用。
传递给 ID3D11DeviceContext1::D iscardResource 的资源必须是使用 D3D11_USAGE_DEFAULT 或 D3D11_USAGE_DYNAMIC 创建的,否则运行时会删除对 DiscardResource 的调用。
传递给 ID3D11DeviceContext1::D iscardView 的视图的资源必须已使用 D3D11_USAGE_DEFAULT 或 D3D11_USAGE_DYNAMIC 创建,否则运行时会删除对 DiscardView 的调用。
如果创建了支持 调试层的设备,则调试输出将报告有关丢弃的调用的错误。
相关主题