Поделиться через


Обработка ошибок

Функции Direct3D версии 10, реализующие драйвер отображения пользовательского режима, обычно имеют VOID для типа возвращаемого параметра. Основным исключением этого правила является функция CalcPrivateObjTypeSize-type (например, функция CalcPrivateResourceSize ). Этот тип функции возвращает тип параметра SIZE_T, указывающий размер области памяти, которую требует драйвер для создания конкретного типа объекта с помощью функции CreateObjType-type (например, CreateResource(D3D10)).

Возвращая VOID, драйвер отображения в пользовательском режиме не уведомляет среду выполнения Direct3D об ошибках обычным способом (то есть с помощью параметра возврата функции драйвера в пользовательском режиме). Вместо этого драйвер отображения в пользовательском режиме должен использовать функцию обратного вызова pfnSetErrorCb среды выполнения Direct3D для передачи такой информации обратно в среду выполнения. Среда выполнения предоставляет указатель на свой pfnSetErrorCb в структуре D3D10DDI_CORELAYER_DEVICECALLBACKS, на которую элемент pUMCallbacks структуры D3D10DDIARG_CREATEDEVICE указывает при вызове функции CreateDevice(D3D10).

Страница со справочной информацией для каждой функции дисплейного драйвера в пользовательском режиме указывает ошибки, о которых функция может сообщать через вызов pfnSetErrorCb. Это означает, что если драйвер отображения в пользовательском режиме вызывает pfnSetErrorCb с кодом ошибки, который не разрешен для текущей функции драйвера в пользовательском режиме, среда выполнения определяет, что условие ошибки является критически важным и действует соответствующим образом. Так как среда выполнения будет действовать соответствующим образом во время pfnSetErrorCb, вы не должны ожидать, что вы можете отменить эффекты вызова pfnSetErrorCb(E_FAIL), вызвав что-то подобное pfnSetErrorCb( S_OK). На самом деле среда выполнения определяет, что S_OK так же критично или недопустимо, как и E_FAIL. Концепция кода возврата S_OK эквивалентна функции драйвера отображения в пользовательском режиме, не вызывая pfnSetErrorCb вообще.

Если runtime Direct3D определяет, что условие ошибки критическое, сначала предпримет действие, записав ошибку через Dr. Watson, который является отладчиком по умолчанию после сбоя (just-in-time). Затем среда выполнения умышленно отключит устройство, чтобы сымитировать сценарий ошибки, связанный с получением кода D3DDDIERR_DEVICEREMOVED. Если потребуется, чтобы драйвер вызывал функцию обратного вызова pfnSetErrorCb, вероятность того, что с каждой ошибкой, возникающей в драйвере, будет ассоциирован полезный стек вызовов, значительно возрастает. Наличие стека вызовов, связанного с ошибкой, позволяет быстро провести диагностику и сгенерировать точные логи Dr. Watson.

В коде драйвера следует использовать pfnSetErrorCb , если в драйвере происходит ошибка, даже если возвращается код ошибки, который среда выполнения не допускает для конкретной функции драйвера, определяется средой выполнения как ошибка драйвера или проблема. Было бы еще хуже, если бы драйвер отображения в пользовательском режиме поглощал критические ошибки и продолжал работу. Драйвер отображения в пользовательском режиме должен вызывать pfnSetErrorCb как можно ближе к точке обнаружения ошибок, чтобы предоставить полезный стек вызовов для посмертной отладки.

В следующей таблице перечислены категории ошибок, которые исполняемая среда Direct3D допускает из определенных функций драйвера.

Категория ошибки Значение

НетОшибок

Драйвер не должен столкнуться с ошибками, включая D3DDDIERR_DEVICEREMOVED. Среда выполнения определит, что любой вызов pfnSetErrorCb является критически важным.

РазрешитьУдалениеУстройства

Драйвер не должен столкнуться с ошибками, за исключением 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. Среда выполнения определит, что любые другие коды ошибок являются критически важными.

РазрешитьПолучениеОшибокДанных

Драйвер должен проверить завершение запроса. Поэтому драйвер может передать DXGI_DDI_ERR_WASSTILLDRAWING через pfnSetErrorCb , если запрос еще не завершен. Драйвер также может передавать D3DDDIERR_DEVICEREMOVED через pfnSetErrorCb. Среда выполнения определит, что любые другие коды ошибок являются критически важными.

РазрешитьОшибкиСчетчикаПроверкиWK

Функция CheckCounter драйвера должна указывать, поддерживает ли она любые счетчики, определенные средой выполнения. Поэтому драйвер может передавать DXGI_DDI_ERR_UNSUPPORTED через pfnSetErrorCb. Среда выполнения определит, что любые другие коды ошибок являются критически важными.

Драйвер не может вернуть D3DDDIERR_DEVICEREMOVED для любой функции check-type.

РазрешитьОшибкиСчетчикаПроверкиDD

Драйвер должен проверить идентификатор счетчика, зависящий от устройства (идентификатор счетчика), чтобы убедиться, что идентификатор счетчика находится в пределах диапазона, и достаточно места для копирования каждой строки счетчика в предоставленный буфер. Драйвер может передавать E_INVALIDARG через pfnSetErrorCb, если параметры заданы некорректно.

Драйвер не может вернуть D3DDDIERR_DEVICEREMOVED для любой функции check-type.