DXUT框架與錯誤處理
Direct3D API的設計使程序能比較容易地處理各種錯誤,盡管大多數Direct3D API函數返回HTRSULT值,但只有一部分函數返回設備錯誤,如D3DERR_DEVICELOST或D3DERR_DRIVERINTERNALERROR。但是通常的Direct3D應用程序使用多種API函數,當傳遞的參數不合要求時,將返回D3DERR_INVALIDCALL。
當開發Direct3D應用程序時,應該檢查所有的API調用是否成功,如果出現一個沒有預測到的失敗調用,應用程序應立即給出通知或記錄該錯誤。使用這種方法,開發人員能很快發現哪些API函數的調用是不正確的。一個正確調用Direct3D
API函數的應用程序應能安全地忽略大多數Direct3D API函數的失敗調用,除了一些關鍵性的API函數,如Present()或TestCooperativeLevel(),這些函數返回的錯誤應用程序不能忽略。
通過僅處理最重要的Direct3D錯誤,可以提高運行速度并使應用程序代碼更健壯,因為代碼中需要處理錯誤的地方并不多。對于為數不多的幾個API函數的失敗調用,必須予以適當處理。
框架中錯誤的處理對應Direct3D API中如何設計錯誤的處理,對于各種各樣的錯誤,如丟失媒體(missing
media),應用程序能通知用戶并終止。對于每一幀都將調用的大多數API函數,錯誤僅在調試時向開發人員顯示一個錯誤消息框來處理,而在發布時這些錯誤都被忽略了。框架用在DXUT.h中定義的幾個宏來完成這一操作:
#if defined(DEBUG) ||
defined(_DEBUG)
#ifndef V
#define V(x) { hr = (x); if( FAILED(hr) ) { DXUTTrace( __FILE__,
(DWORD)__LINE__, hr, L#x, true ); } }
#endif
#ifndef V_RETURN
#define V_RETURN(x) { hr = (x); if( FAILED(hr) ) { return DXUTTrace( __FILE__,
(DWORD)__LINE__, hr, L#x, true ); } }
#endif
#else
#ifndef V
#define V(x) { hr = (x); }
#endif
#ifndef V_RETURN
#define V_RETURN(x) { hr = (x); if( FAILED(hr) ) { return hr; } }
#endif
#endif
當使用vs.net時,如果想跳到出錯代碼所在的行,只需簡單地雙擊調試輸出窗口中輸出的錯誤信息行即可。
選擇最可行的設備
DXUT使用高度靈活的方法從枚舉集合中選擇最好的設備,這個設備枚舉和分級系統可以通過調用函數DXUTFindValidDeviceSettings()獨立于框架使用,該函數的聲明如下:
Finds valid device settings to be used to create a new
device.
HRESULT DXUTFindValidDeviceSettings(
DXUTDeviceSettings * pOut,
DXUTDeviceSettings * pIn,
DXUTMatchOptions * pMatchOptions
);
Parameters
- pOut
- [out] Pointer to a DXUTDeviceSettings structure
that contains valid settings for the new device.
- pIn
- [in] Pointer to a DXUTDeviceSettings
structure that contains desired settings for the new device. The default
value is NULL.
- pMatchOptions
- [in] Pointer to a DXUTMatchOptions structure that
contains flags describing how to use the device settings when choosing valid
output device settings. Optimal device settings will be created based upon
the match values in DXUTMatchOptions. If NULL, the function acts as
if all members of this structure were DXUTMT_IGNORE_INPUT, meaning that the
function will return valid device settings as close as possible to default
device settings. See Remarks. The default value is NULL.
Return Values
If the function succeeds, the return value is S_OK. If
the function fails, the return value can be one of the error codes in DXUTERR.
Remarks
This function attempts to find valid device settings
based upon the input device settings, given by pIn. For each device setting, a
match option in the DXUTDeviceSettings structure specifies how the
function makes decisions. The function works for both Direct3D 9 and Direct3D 10
device settings.
This function is internally by DXUT used when toggling
between full screen and windowed modes, when selecting between HAL and REF
device types, and inside DXUTCreateDevice.
DXUTMatchOptions
Describes match options for finding valid device
settings using the DXUTFindValidDeviceSettings function. Each member of this
structure corresponds to a setting described by the DXUTDeviceSettings
structure.
Default values are used when a member is set to
DXUTMT_IGNORE_INPUT. See Remarks.
typedef struct DXUTMatchOptions {
DXUT_MATCH_TYPE eAPIVersion;
DXUT_MATCH_TYPE eAdapterOrdinal;
DXUT_MATCH_TYPE eOutput;
DXUT_MATCH_TYPE eDeviceType;
DXUT_MATCH_TYPE eWindowed;
DXUT_MATCH_TYPE eAdapterFormat;
DXUT_MATCH_TYPE eVertexProcessing;
DXUT_MATCH_TYPE eResolution;
DXUT_MATCH_TYPE eBackBufferFormat;
DXUT_MATCH_TYPE eBackBufferCount;
DXUT_MATCH_TYPE eMultiSample;
DXUT_MATCH_TYPE eSwapEffect;
DXUT_MATCH_TYPE eDepthFormat;
DXUT_MATCH_TYPE eStencilFormat;
DXUT_MATCH_TYPE ePresentFlags;
DXUT_MATCH_TYPE eRefreshRate;
DXUT_MATCH_TYPE ePresentInterval;
} DXUTMatchOptions, *LPDXUTMatchOptions;
Members
- eAPIVersion
- Match type for the API version.
- eAdapterOrdinal
- Match type for the display adapter ordinal.
- eOutput
- Match type for the adapter output ordinal.
- eDeviceType
- Match type for the enumerated type of the device.
If set to DXUTMT_IGNORE_INPUT, then the default value is D3DDEVTYPE_HAL.
- eWindowed
- Match type for the windowed or full-screen mode.
if set to DXUTMT_IGNORE_INPUT, then the default value is windowed mode
(TRUE).
- eAdapterFormat
- Match type for the adapter surface format. If set
to DXUTMT_IGNORE_INPUT, then the default value is the desktop display mode,
or D3DFMT_X8R8G8B8 if the desktop display mode is less than 32 bits.
- eVertexProcessing
- Match type for the vertex processing flags
D3DCREATE_HARDWARE_VERTEXPROCESSING, D3DCREATE_MIXED_VERTEXPROCESSING, or
D3DCREATE_SOFTWARE_VERTEXPROCESSING. if set to DXUTMT_IGNORE_INPUT, then the
default value is D3DCREATE_HARDWARE_VERTEXPROCESSING.
- eResolution
- Match type for the display mode resolution. if set
to DXUTMT_IGNORE_INPUT, then the default value is 640 x 480 pixels for
windowed mode, or the desktop resolution for full-screen mode.
- eBackBufferFormat
- Match type for the back buffer format. if
BackBufferFormat is set to DXUTMT_IGNORE_INPUT, then the default value is to
match the adapter format.
- eBackBufferCount
- Match type for the number of back buffers. if
BackBufferCount is set to DXUTMT_IGNORE_INPUT, then the default value is 2
for triple buffering.
- eMultiSample
- Match type for the quality level. if set to
DXUTMT_IGNORE_INPUT, then the default value is to disable multisampling
(MultiSampleQuality = 0).
- eSwapEffect
- Match type for the swap effect. if set to
DXUTMT_IGNORE_INPUT, then the default value is D3DSWAPEFFECT_DISCARD.
- eDepthFormat
- Match type for the depth format of the automatic
depth-stencil surface that the device will create. If both eDepthFormat and
eStencilFormat are set to DXUTMT_IGNORE_INPUT, then the default value is
D3DFMT_D16 if the backbuffer format is 16 bits or less, or D3DFMT_D32
otherwise.
- eStencilFormat
- Match type for the stencil format of the automatic
depth-stencil surface that the device will create. if both eDepthFormat and
eStencilFormat are set to DXUTMT_IGNORE_INPUT, then the default value is
D3DFMT_D16 if the backbuffer format is 16 bits or less, or D3DFMT_D32
otherwise.
- ePresentFlags
- Match type for the presentation parameters flags.
if set to DXUTMT_IGNORE_INPUT, then the default value is
D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL.
- eRefreshRate
- Match type for the rate at which the display
adapter refreshes the screen. If set to DXUTMT_IGNORE_INPUT, then the
default value is 0, indicating windowed mode.
- ePresentInterval
- Match type for the presentation interval. if set
to DXUTMT_IGNORE_INPUT, then the default value is
D3DPRESENT_INTERVAL_IMMEDIATE for windowed mode, or
D3DPRESENT_INTERVAL_DEFAULT for full-screen mode.
Remarks
For each member of this structure, match options are
specified using the constant values of the DXUT_MATCH_TYPE enumeration, as in
the following code example.
matchOptions.eResolution = DXUTMT_CLOSEST_TO_INPUT;
To use default device settings instead, use the
DXUTMT_IGNORE_INPUT flag as follows:
matchOptions.eResolution = DXUTMT_IGNORE_INPUT;
DXUT_MATCH_TYPE
Describes how to match input device settings when
creating a new device with a function.
typedef enum DXUT_MATCH_TYPE
{
DXUTMT_IGNORE_INPUT = 0,
DXUTMT_PRESERVE_INPUT,
DXUTMT_CLOSEST_TO_INPUT,
} DXUT_MATCH_TYPE, *LPDXUT_MATCH_TYPE;
Constants
- DXUTMT_IGNORE_INPUT
- Ignore the device setting input, and return a
device setting as close as possible to a default device setting.
- DXUTMT_PRESERVE_INPUT
- Return without changing the device setting that
was given as input to the function.
- DXUTMT_CLOSEST_TO_INPUT
- Return a device setting as close as possible to
the device setting that was given as input to the function.
假設想要獲取一個硬件抽象層設備,其后臺緩沖區格式是D3DFMT_A2B10G10R10,如果系統中的硬件抽象層設備不支持這種后臺緩沖區格式,但有一個安裝好的參考設備支持,那么該函數可以使用該參考設備或根據硬件抽象層設備改變后臺緩沖區格式,這都將通過枚舉類型DXUT_MATCH_TYPE來控制如何采用設備格式。