D3D11: эталонный растеризатор против WARP - PullRequest
0 голосов
/ 25 сентября 2019

У меня есть тест для пиксельного шейдера, который выполняет некоторую визуализацию и сравнивает результат с эталонным изображением, чтобы убедиться, что шейдер выдает ожидаемый результат.Когда этот тест выполняется на компьютере CI, он находится на виртуальной машине без графического процессора, поэтому я вызываю D3D11CreateDevice с D3D_DRIVER_TYPE_REFERENCE, чтобы использовать эталонный растеризатор.Мы годами занимались этим без проблем на виртуальной машине Windows 7.

Сейчас мы пытаемся перейти на виртуальную машину Windows 10 для наших тестов CI.Когда я запускаю тест здесь, различные вызовы API начинают давать сбой после некоторого количества успешных тестов (порядка 5000-10000) с DXGI_ERROR_DEVICE_REMOVED, и вызов GetDeviceRemovedReason возвращает DXGI_ERROR_DRIVER_INTERNAL_ERROR.После некоторой отладки я обнаружил, что ошибка возникает во время вызова ID3D11DeviceContext :: PSSetShader (да, это возвращает void, но я нашел это через точку останова в KernelBase.dll! RaiseException).Насколько я могу судить, этот вызов выглядит точно так же, как и тысячи предыдущих вызовов PSSetShader.Кажется, это не проблема с ресурсом, процесс использует только 8 МБ памяти при возникновении ошибки, а количество дескрипторов не увеличивается.

Я могу воспроизвести проблему на нескольких системах Win10, и этоуспешно на нескольких системах Win7.Большая разница между ними заключается в том, что в Win7 вызовы API проходят через d3d11ref.dll, а в Win10 - через d3d10warp.dll.Я не совсем знаком с тем, в чем заключаются различия или почему будет выбран тот или иной вариант, и документация MSDN довольно непрозрачна по этому вопросу.Я знаю, что и d3d11ref.dll, и d3d10warp.dll присутствуют как на сбойных, так и на проходящих системах;Я не знаю, какова логика загрузки одного или другого для одного и того же набора вызовов или почему происходит сбой библиотеки d3d10warp.

Итак, кто-то может объяснить разницу между ними и / илиподскажите, как я могу получить d3d11ref.dll для загрузки в Windows 10?Насколько я могу судить, это ошибка в d3d10warp.dll, и сейчас я просто хотел бы обойти ее.

В случае, если это имеет значение, я вызываю D3D11CreateDevice с желаемым уровнем возможностей, установленным в D3D_FEATURE_LEVEL_11_0, и я проверяю, что тот же уровень возвращается как достигнутый.Я передаю 0 для creationFlags, и мой D3D11_SDK_VERSION определен как 7 в d3d11.h.Ниже приведен стек вызовов выше PSSetShader, когда происходит сбой.Похоже, это первый сбойный вызов, и каждый последующий вызов с кодом возврата также завершается неудачей.

KernelBase.dll!RaiseException()
KernelBase.dll!OutputDebugStringA()
d3d11.dll!CDevice::RemoveDevice(long)
d3d11.dll!NDXGI::CDevice::RemoveDevice()
d3d11.dll!CContext::UMSetError_()
d3d10warp.dll!UMDevice::MSCB_SetError(long,enum UMDevice::DDI_TYPE)
d3d10warp.dll!UMContext::SetShaderWithInterfaces(enum PIXELJIT_SHADER_STAGE,struct D3D10DDI_HSHADER,unsigned int,unsigned int const *,struct D3D11DDIARG_POINTERDATA const *)
d3d10warp.dll!UMDevice::PsSetShaderWithInterfaces(struct D3D10DDI_HDEVICE,struct D3D10DDI_HSHADER,unsigned int,unsigned int const *,struct D3D11DDIARG_POINTERDATA const *)
d3d11.dll!CContext::TID3D11DeviceContext_SetShaderWithInterfaces_<1,4>(class CContext *,struct ID3D11PixelShader *,struct ID3D11ClassInstance * const *,unsigned int)
d3d11.dll!CContext::TID3D11DeviceContext_SetShader_<1,4>()
MyTest.exe!MyFunctionThatCallsPSSetShader()

1 Ответ

0 голосов
/ 26 сентября 2019

Проблема в том, что вы не включили опциональную функцию Windows 10 «Графические инструменты» в этой системе.Таким образом вы устанавливаете среду отладки DirectX 11/12 в Windows 10, включая эталонное устройство Direct3D 11, WARP для DirectX 12, уровень отладки DirectX SDK для DX11 / DX12 и т. Д.

WARP для DirectX11 доступна во всех системах, а не только в тех, которые имеют функцию «Графические инструменты».Вообще говоря, большинство людей перешли на использование WARP вместо программного драйвера, поскольку это намного быстрее.Если у вас возникают сбои в режиме WARP, вам следует выяснить источник этих сбоев, включив устройство DEBUG.

См. этот пост .

...