Обработка ошибок
Функции Direct3D версии 10, которые реализует драйвер отображения пользовательского режима, обычно имеют VOID для возвращаемого типа параметра. Основным исключением из этого правила является функция CalcPrivateObjTypeSize-type (например, функция CalcPrivateResourceSize ). Функция этого типа возвращает SIZE_T тип параметра, указывающий размер области памяти, необходимый драйверу для создания определенного типа объекта с помощью функции CreateObjType-type (например, CreateResource(D3D10)).
Возврат VOID запрещает драйверу отображения пользовательского режима уведомлять среду выполнения Direct3D об ошибках обычным способом (т. е. с помощью возвращаемого параметра функции драйвера отображения пользовательского режима). Вместо этого драйвер отображения пользовательского режима должен использовать функцию обратного вызова pfnSetErrorCb среды выполнения Direct3D для передачи таких сведений обратно в среду выполнения. Среда выполнения предоставляет указатель на свой pfnSetErrorCb в структуре D3D10DDI_CORELAYER_DEVICECALLBACKS, на которую указывает элемент pUMCallbackструктуры D3D10DDIARG_CREATEDEVICE при вызове функции CreateDevice(D3D10).
Справочная страница для каждой функции драйвера отображения пользовательского режима указывает ошибки, которые функция может передавать через вызов pfnSetErrorCb. Это означает, что если драйвер отображения пользовательского режима вызывает pfnSetErrorCb с кодом ошибки, который не разрешен для текущей функции драйвера отображения пользовательского режима, среда выполнения определяет, что условие ошибки является критическим и действует соответствующим образом. Так как среда выполнения будет действовать надлежащим образом во время pfnSetErrorCb, не следует ожидать, что вы сможете обратить вспять эффект вызова pfnSetErrorCb( E_FAIL ), вызвав нечто вроде pfnSetErrorCb( S_OK ). На самом деле среда выполнения определяет, что S_OK так же недействительна или критична, как и E_FAIL. Концепция кода возврата S_OK эквивалентна функции драйвера отображения в пользовательском режиме, не вызывающей pfnSetErrorCb .
Если среда выполнения Direct3D определяет, что состояние ошибки является критическим, она сначала примет меры, записав ошибку в журнал с помощью доктора Уотсона — отладчика по умолчанию (JIT) по умолчанию. Затем среда выполнения потеряет устройство намеренно, тем самым эмулируя сценарий получения кода ошибки D3DDDIERR_DEVICEREMOVED. Если драйвер должен вызывать функцию обратного вызова pfnSetErrorCb , вероятность того, что с каждой ошибкой, исходящей из драйвера, будет связан полезный стек вызовов. Наличие стека вызовов, связанного с ошибкой, обеспечивает быструю диагностику и точные журналы доктора Уотсона.
Вы должны использовать pfnSetErrorCb в коде драйвера, если в драйвере что-то идет не так, даже если возврат кода ошибки, который среда выполнения не разрешает для конкретной функции драйвера, определяется средой выполнения как ошибка драйвера или проблема. Еще хуже было бы для драйвера отображения пользовательского режима, чтобы поглощать критические ошибки и продолжать работу. Драйвер отображения пользовательского режима должен вызывать pfnSetErrorCb как можно ближе к точке обнаружения ошибок, чтобы обеспечить полезный стек вызовов для последующей отладки.
В следующей таблице перечислены категории ошибок, разрешенных средой выполнения Direct3D для определенных функций драйвера.
Категория ошибки | Значение |
---|---|
NoErrors |
Драйвер не должен столкнуться с ошибками, включая D3DDDIERR_DEVICEREMOVED. Среда выполнения определит, что любой вызов pfnSetErrorCb является критическим. |
AllowDeviceRemoved |
Драйвер не должен столкнуться с ошибками, за исключением D3DDDIERR_DEVICEREMOVED. Среда выполнения определит, что любой вызов pfnSetErrorCb , который не проходит D3DDDIERR_DEVICEREMOVED, является критическим. Драйвер не обязан возвращать DEVICEREMOVED, если устройство было удалено. Однако среда выполнения позволяет драйверу возвращать DEVICEREMOVED на случай, если ФУНКЦИЯ DEVICEREMOVED вмешалась в функцию драйвера, что обычно не должно происходить. |
AllowOutOfMemory |
Возможно, у драйвера может быть нехватка памяти. Таким образом, драйвер может передавать E_OUTOFMEMORY и D3DDDIERR_DEVICEREMOVED через pfnSetErrorCb. Среда выполнения определит, что все другие коды ошибок являются критическими. |
AllowCounterCreationErrors |
Возможно, у драйвера может быть нехватка памяти. Драйвер также может не создавать счетчики из-за исключительной природы счетчиков. Таким образом, драйвер может передавать E_OUTOFMEMORY, DXGI_DDI_ERR_NONEXCLUSIVE и D3DDDIERR_DEVICEREMOVED через pfnSetErrorCb. Среда выполнения определит, что все другие коды ошибок являются критическими. |
AllowMapErrors |
Драйвер должен проверка для состязания за ресурсы. Таким образом, драйвер может передавать DXGI_DDI_ERR_WASSTILLDRAWING через pfnSetErrorCb , если флаг D3D10_DDI_MAP_FLAG_DONOTWAIT был передан в функцию ResourceMap драйвера. Драйвер также может передавать D3DDDIERR_DEVICEREMOVED через pfnSetErrorCb. Среда выполнения определит, что все другие коды ошибок являются критическими. |
AllowGetDataErrors |
Драйвер должен проверка для завершения запроса. Таким образом, драйвер может передать DXGI_DDI_ERR_WASSTILLDRAWING через pfnSetErrorCb , если запрос еще не завершен. Драйвер также может передавать D3DDDIERR_DEVICEREMOVED через pfnSetErrorCb. Среда выполнения определит, что все другие коды ошибок являются критическими. |
AllowWKCheckCounterErrors |
Функция CheckCounter драйвера должна указывать, поддерживает ли она какие-либо счетчики, определенные средой выполнения. Таким образом, драйвер может передавать DXGI_DDI_ERR_UNSUPPORTED через pfnSetErrorCb. Среда выполнения определит, что все другие коды ошибок являются критическими. Драйвер не может возвращать D3DDDIERR_DEVICEREMOVED для любой функции проверка типа. |
AllowDDCheckCounterErrors |
Драйвер должен проверить идентификатор счетчика, зависящий от устройства ( идентификатор счетчика), чтобы убедиться, что идентификатор счетчика находится в пределах диапазона и имеется достаточно места для копирования каждой строки счетчика в предоставленный буфер. Драйвер может передавать E_INVALIDARG через pfnSetErrorCb, если параметры таким образом неверны. Драйвер не может возвращать D3DDDIERR_DEVICEREMOVED для любой функции проверка типа. |