Устранение сбоев D3D12 GPU на Windows
Катастрофа GPU может привести к неожиданному закрытию Unity Editor и возврату графической ошибки, например, Unrecoverable D3D12 device error! Run with -force-d3d12-debug and see logs for more info. Диагностика этих аварий часто затруднена, поскольку причина может находиться не в коде проекта. На этой странице объясняется, как определить источник аварии GPU и предоставляется набор шагов для устранения неполадок и разрешения аварий GPU.
Типы аварий
Существует ряд ошибок, с которыми вы можете столкнуться, которые называются сбоями GPU при разработке в Unity:
-
GPU тайм-аут: Когда графическая команда занимает слишком много времени для выполнения операции, Windows прервет операцию и перезапустит графический драйвер, что приведет к сбою. Например:
- Бесконечная петля в шейдере, вызванная устаревшими или неинициализированными данными.
- Примитивы синхронизации в коде вычислительного шейдера, например
GroupMemoryBarrierWithGroupSync, когда вычислительный поток пропускает вызов.
- Промах страницы памяти GPU: Возникает, когда графическая команда пытается получить доступ к памяти GPU, которая больше не доступна, например, к буферу, который был освобожден до того, как GPU закончил его использование. Это действие приводит к сбою.
- Сбой графического драйвера: Ошибка возникает в сторонней библиотеке динамических связей (файл .dll), которую Unity вызывает для выполнения таких задач, как компиляция шейдеров и распределение ресурсов.
- GPU сбой: Сбой на уровне аппаратного обеспечения, часто вызванный тем, что GPU исчерпал выделенную видеопамять (VRAM).
Понимание стека драйверов
Unity не взаимодействует напрямую с вашим GPU. Вместо этого, он опирается на слоистый стек драйверов между вашим проектом и оборудованием. Этот стек содержит множество динамически связанных библиотек (DLLs). Каждая библиотека действует как мост в конвейере рендеринга, обрабатывая такие задачи, как компиляция шейдеров, управление ресурсами и перевод команд.
Когда что-то не так в одном из этих DLLs, последствия могут быть серьезными. Поскольку они работают на системном уровне, традиционные методы отладки зачастую неадекватны. Вы все еще можете получить ценную информацию от серверов символов драйверов, но вы не можете просмотреть код драйвера, как вы можете с вашим собственным кодом.
Поэтому понимание архитектуры графического драйвера имеет важное значение. Порядок действий следующий:
- DLLs, которые вы найдете в журналах сбоев, почти всегда являются драйверами пользовательского режима (UMDs). Они запускаются в процессном пространстве вашего приложения и обрабатывают компиляцию шейдеров, создание командного буфера и управление ресурсами. Когда они срываются, ваше приложение с ними срывается, поэтому Unity внезапно закрывается.
- Драйвер режима ядра (KMD) работает на более низком уровне и управляет доступом к оборудованию для всех приложений. Катастрофы KMD более серьезны и могут вызывать синие экраны, хотя современный Windows часто может восстановиться, перезапустив драйвер.
Драйверы пользовательского режима сложны, так как они отвечают за компиляцию шейдеров, управление GPU памятью и ресурсами, а также зачастую обходят ошибки в приложениях.
Авария обычно происходит, когда водитель сталкивается с неожиданной ситуацией, такой как:
- Шейдер, содержащий необычный шаблон, который вызывает ошибку компилятора.
- Непроверенная последовательность вызовов API из приложения.
- Коррупция в собственном кэше драйвера шейдера.
- Ошибки, связанные с оборудованием, которые появляются только при определенных условиях.
Исключить проблемы системного уровня
Перед непосредственным устранением неполадок драйвера важно исключить другие проблемы системного уровня.
Проверить следующее:
- Отключить накладки: Приложения, которые отображают накладки, такие как Discord, Steam или MSI Afterburner, могут мешать процессу отображения Unity. Отключите или закройте это программное обеспечение перед запуском Редактора.
- Сброс состояния GPU к значениям по умолчанию: Если вы разогнать ваш GPU, вернуть его к своей заводской частоте часов по умолчанию. Кроме того, открыть ваш GPU панели управления и восстановить все настройки по умолчанию. На некоторых ноутбуках, восстановление настроек по умолчанию может привести к системе использовать интегрированный GPU вместо выделенного GPU, особенно когда ноутбук не подключен к источнику питания или имеет низкий уровень заряда батареи. Интегрированный GPUs обычно имеют меньшую мощность обработки и может иметь больше проблем совместимости, так что убедитесь, что вы настроить Unity Editor и Player для запуска на вашей выделенной GPU.
- Проверка обновлений операционной системы: Убедитесь, что ваша операционная система полностью обновлена. Microsoft часто выпускает патчи, которые могут решить проблемы стабильности с основными компонентами, такими как DirectX.
- Обновление графических драйверов: Устаревшие драйверы являются распространенным источником сбоев и проблем с отображением. Рекомендуется обновить драйверы до последней версии с помощью таких инструментов, как NVIDIA GeForce Experience или AMD Software: Adrenalin Edition.
- Запустить сканирование системных файлов: Чтобы проверить и восстановить поврежденные файлы Windows, откройте командную строку как администратор и запустите
sfc /scannow, затемDISM /Online /Cleanup-Image /RestoreHealth.
Определение типа аварии
Сбой обычно является либо проблемой с драйвером видеокарты, либо проблемой с оборудованием GPU.
Чтобы найти причину, вам нужно изучить журнал сбоев. Местоположение отчетов о сбоях на вашем компьютере смотрите в файлах журнала ссылка.
Наблюдение симптомов и анализ журнала редактора
Общие симптомы отказа, связанного с GPU, включают:
- Высокая нагрузка GPU перед аварией.
- Визуальные сбои или зависания в редакторе.
- Внезапный выход редактора.
- Windows сброс драйвера дисплея.
Если Unity перехватывает сбой, вы можете изучить след стека в конце файла Editor.log. Сбой, связанный с графикой, обычно показывает определенный след стека, который включает поток отображения Unity и графический поток API..
- Отказ потока рендеринга: Трек стека включает
GfxDeviceWorker::RunGfxDeviceWorker. Это указывает на то, что движок вышел из строя во время отправки инструкций GPU, а не во время стандартной игровой логики. - Вызовы графического API: В трассировке стека упоминается графический слой API, например
D3D12Fence::Wait. - Коды ошибок устройства: Журнал содержит ошибки типа
Device failed error (887a0006)илиDevice removal. - Состояние памяти GPU: Журнал может указывать на состояние памяти, например:
d3d12: GfxDevice was not out of Local memory.
Стек вызовов может выглядеть следующим образом:
========== OUTPUTTING STACK TRACE ==================
0x00007FFF7F3580DA (KERNELBASE) RaiseException
0x00007FFDF037F596 (Unity) LaunchBugReporter
0x00007FFDF0BC03A7 (Unity) EditorMonoConsole::LogToConsoleImplementation
0x00007FFDF0BC0EE3 (Unity) EditorMonoConsole::LogToConsoleImplementation
0x00007FFDF2AA2ED8 (Unity) DebugStringToFilePostprocessedStacktrace
0x00007FFDF2AA26E1 (Unity) DebugStringToFile
0x00007FFDF21608F5 (Unity) CheckDeviceStatus
0x00007FFDF21CB7A2 (Unity) CheckCompletedValue
0x00007FFDF21D1E70 (Unity) D3D12Fence::Wait
0x00007FFDF2195721 (Unity) GfxDeviceD3D12::QueuePresent
0x00007FFDF21C20DE (Unity) D3D12Window::EndRendering
0x00007FFDF1D077CD (Unity) GfxDeviceWorker::RunCommand
0x00007FFDF1D09FCC (Unity) GfxDeviceWorker::RunExt
0x00007FFDF1D0A0FF (Unity) GfxDeviceWorker::RunGfxDeviceWorker
0x00007FFDF2AC12FC (Unity) Thread::RunThreadWrapper
0x00007FFF80CBE8D7 (KERNEL32) BaseThreadInitThunk
0x00007FFF81F2C53C (ntdll) RtlUserThreadStart
========== END OF STACKTRACE ===========
Журнал может также указать на конкретный скрипт или ресурс, из-за которого GPU перешёл в критическое состояние. Например, ссылка на CreateResources в журнале может отслеживаться до конкретного скрипта и номера строки:
CreateResources
...
GPUCrash:CreateResources () (at Assets/GPUCrash.cs:25)
GPUCrash:Update () (at Assets/GPUCrash.cs:47)
Подробные журналы сбоев
Чтобы просмотреть подробные журналы, проверьте следующие предварительные условия:
- Ваше устройство должно работать Windows 11.
- Вы должны включить Майкрософта Диагностические средства графики
- Запустите редактор со следующими аргументами:
-force-d3d12-debug-force-d3d12-editor-pix-events
Примечание: Вы также можете использовать аргумент -force-d3d12-debug-gbv возвращать информацию о сбоях, однако, это рекомендуется только как второстепенный шаг в процессе отладки. GPU- основанная на подтверждении (GBV), что может добавить большое количество отладочной информации в журналы сбоев. Проанализируйте журнал без этого флага, чтобы избежать создания больших файлов.
Эти аргументы включают API Device Removed Extended Data (DRED) от Microsoft, которые могут дать больше сведений о состоянии GPU в момент сбоя.
В журнале ошибки отображаются в следующих форматах:
- Ошибки проверки:
d3d12 validation error: <message> - Ошибки DXGI:
d3d12 DXGI error: <message>
DLL ссылка
Для большинства сбоев, имя файла .dll в вашем журнале сбоев является ключом к идентификации источника. Подавляющее большинство из них происходит в User-Mode Driver (UMD), который переводит команды из графики APIs, как DirectX в инструкции, которые ваш GPU может понять.
| DLL файл | Производитель | Тип | Описание |
|---|---|---|---|
amdxc64.dll |
AMD | UMD | Определяет, используются ли DirectX, OpenGL или Vulkan графики API. |
atidxx64.dll |
AMD | UMD | Преобразует DirectX API вызов, шейдеры и ресурсы в GPU специфические структуры. |
igc64.dll |
Интел | UMD | Компиляция HLSL или GLSL в оптимизированный машинный код для архитектуры Intel GPU. Катастрофы здесь часто указывают на проблемы компиляции шейдера. Например, это может быть вызвано тем, что шейдер использует функции неожиданным образом или попадает в ошибки компилятора. |
igd10um64.dll |
Интел | UMD | Преобразует DirectX API вызов, шейдеры и ресурсы в GPU-специфическую структуру для более старых Intel GPUs, например Intel HD/UHD Graphics pre–11th gen. |
igd10um64xe.dll |
Интел | UMD | Преобразует DirectX API вызовы, шейдеры и ресурсы в GPU специфические структуры для современной архитектуры Xe (11-е поколение Core и более новые, включая Arc GPUs). |
nvwgf2umx.dll |
NVIDIA | UMD | Преобразует DirectX API вызов, шейдеры и ресурсы в GPU специфические структуры. |
nvoglv64.dll |
NVIDIA | UMD | Если вы выберете OpenGL вместо DirectX, это переводит вызов OpenGL на API, компилирует GLSL шейдеры и управляет всем конвейером рендеринга OpenGL. |
Исправить сбой графического драйвера
После идентификации драйвера выполните следующие действия, чтобы устранить проблему.
1. Выполнить чистую установку драйвера
Обновление драйвера не всегда достаточно, чтобы исправить аварию. Чистая установка удаляет все старые и потенциально поврежденные файлы перед установкой свежей версии.
-
AMD:
- Используйте официальный AMD Cleanup Utility или сторонний инструмент, как Display Driver Uninstaller (DDU), чтобы полностью удалить все существующие файлы драйверов.
- Загрузите и установите последний стабильный драйвер с официального сайта AMD. Если сбои начались после обновления, рассмотрите возможность возврата к ранее стабильной версии.
-
NVIDIA:
- Загрузите последний драйвер Game Ready или Studio с сайта NVIDIA.
- Запустите установщик и выберите Custom (Advanced).
- На следующем экране установите флажок Выполнить чистую установку и продолжайте. Для стойких проблем используйте DDU перед переустановкой.
-
Интел:
- Используйте инструмент очистки, такой как DDU, чтобы удалить все существующие файлы драйверов.
- Загрузите и установите самые последние драйверы графики от официального центра загрузки Intel или вебсайта производителя компьютера.
Если сбой продолжается, попробуйте установить более старую версию драйвера.
2. Очистить кэш шейдера
Поврежденные кэши шейдеров, поддерживаемые Unity и графическим драйвером, могут вызывать повторяющиеся сбои компиляции. Чтобы полностью очистить кэши, удалите содержимое следующих папок:
| Тип кэша | Местоположение | Описание |
|---|---|---|
| Кэш шейдера Unity | Library/ShaderCache |
Удалите содержимое этой папки, чтобы очистить кэш шейдера библиотеки проекта для Unity Editor. |
| Кэш драйвера шейдера | %LOCALAPPDATA%\AMD\DxCache %LOCALAPPDATA%\AMD\DxcCache %LOCALAPPDATA%\AMD\VkCache %LOCALAPPDATA%\AMD\GLCache %LOCALAPPDATA%\AMD\DX9Cache %LOCALAPPDATA%\Intel\ShaderCache %LOCALAPPDATA%\NVIDIA\DXCache %LOCALAPPDATA%\D3DSCache %ProgramFiles(x86)%\Steam\steamapps\shadercache |
Удалите содержимое этих папок, чтобы очистить кэш драйвера шейдера для встроенного проигрывателя. |
После очистки этих кэшей перезапустите компьютер, чтобы убедиться, что в памяти не осталось никаких кэшируемых шейдеров.
3. Используйте резервную графику API
Если сбой связан с DX12, можно временно возвратиться к DX11, пока вы исследуете корневую причину. Используйте D3D12 Ассет фильтрации устройств для создания резерва.
Сообщите о сбоях по адресу Unity
Если вы испробовали решения, описанные в этом документе, и сбой по-прежнему сохраняется, вы можете отправить сообщение об ошибке. При отправке сообщения включите как можно больше подробностей и перечислите действия по воспроизведению проблемы.
Более подробную информацию о сообщении об ошибках см. в Как сообщать об ошибках.
Дополнительные ресурсы
- Ссылка на файлы журнала
- Введение в D3D12 Актив фильтрации устройств
- Как сообщить об ошибках