2016-02-13 6 views
1

Я получаю странную ошибку при создании командной строки DirectX 12. Другие приложения DX12 могут успешно запускаться на одной машине.Устройство DirectX 12 приостановлено сразу после создания

Мой компьютер использует блок D3D_FEATURE_LEVEL_11_0if. Графическая карта, используемая для тестирования NVIDIA GT 740, с 361.75 драйверов

Это код используется (свернутом):

#include <Windows.h> 
#include <d3d12.h> 
#include <dxgi1_4.h> 
#include <comdef.h> 
#include <D3d12sdklayers.h> 
#include <string> 

#pragma comment(lib,"d3d12.lib") 
#pragma comment(lib,"dxgi.lib") 
#pragma comment(lib,"d3dcompiler.lib") 
using namespace std; 

LRESULT WINAPI WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { 
    switch (msg) 
    { 
    case WM_DESTROY: 
     PostQuitMessage(0); 
     return 0; 
    default: 
     return DefWindowProc(hwnd, msg, wParam, lParam); 
    } 
} 
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 
    LPTSTR lpCmdLine, int nCmdShow) { 
    UNREFERENCED_PARAMETER(hPrevInstance); 
    UNREFERENCED_PARAMETER(nCmdShow); 
    UNREFERENCED_PARAMETER(lpCmdLine); 

    wchar_t* WindowClass = L"Papergate"; 
    WNDCLASSEX wc; 
    ZeroMemory(&wc, sizeof(WNDCLASSEX)); 

    wc.cbSize = sizeof(WNDCLASSEX); 
    wc.style = CS_HREDRAW | CS_VREDRAW; 
    wc.lpfnWndProc = WndProc; 
    wc.hInstance = hInstance; 
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 2); 
    wc.lpszClassName = WindowClass; 

    if (!RegisterClassEx(&wc)) 
    { 
     return 1; 
    } 

    HWND hwnd = CreateWindowEx(NULL, wc.lpszClassName, WindowClass, 
     WS_OVERLAPPEDWINDOW, 
     CW_USEDEFAULT, CW_USEDEFAULT, 
     CW_USEDEFAULT, CW_USEDEFAULT, 
     NULL, NULL, hInstance, NULL); 

    if (!hwnd) 
    { 
     UnregisterClass(WindowClass, hInstance); 
     return 1; 
    } 
    ShowWindow(hwnd, SW_SHOWDEFAULT); 
    UpdateWindow(hwnd); 

    ID3D12Device* device; 
    HRESULT result = D3D12CreateDevice(NULL, D3D_FEATURE_LEVEL_12_1, 
     __uuidof(ID3D12Device), (void**)&device); 
    if (FAILED(result)) 
    { 
     result = D3D12CreateDevice(NULL, D3D_FEATURE_LEVEL_12_0, 
      __uuidof(ID3D12Device), (void**)&device); 
     if (FAILED(result)) 
     { 
      result = D3D12CreateDevice(NULL, D3D_FEATURE_LEVEL_11_0, 
       __uuidof(ID3D12Device), (void**)&device); 
      if (FAILED(result)) { 
       _com_error error(result); 
       MessageBox(hwnd, error.ErrorMessage(), 
        (wstring(L"Error: ") + to_wstring(__LINE__)).c_str(), 
        MB_OK); 
       return 2; 
      } 
     } 
    } 

    ID3D12Debug* debugInterface; 
    if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&debugInterface)))) 
    { 
     debugInterface->EnableDebugLayer(); 
    } 

    D3D12_COMMAND_QUEUE_DESC commandQueueDesc; 
    commandQueueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; 
    commandQueueDesc.NodeMask = 0; 
    commandQueueDesc.Priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL; 
    commandQueueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; 
    ID3D12CommandQueue* commandQueue; 
    result = device->CreateCommandQueue(&commandQueueDesc, __uuidof(ID3D12CommandQueue), (void**)&commandQueue); 
    if (FAILED(result)) { 
     _com_error error(result); 
     MessageBox(hwnd, error.ErrorMessage(), 
      (wstring(L"Error: ") + to_wstring(__LINE__)).c_str(), MB_OK); 
     result = device->GetDeviceRemovedReason(); 
     error = _com_error(result); 
     MessageBox(hwnd, error.ErrorMessage(), 
      (wstring(L"Error: ") + to_wstring(__LINE__)).c_str(), MB_OK); 
     debugInterface->Release(); device->Release(); return 2; 
    } 

    MSG msg; 
    ZeroMemory(&msg, sizeof(MSG)); 
    while (GetMessage(&msg, NULL, 0, 0) && msg.message != WM_QUIT) 
    { 
     TranslateMessage(&msg); 
     DispatchMessage(&msg); 
    } 

    commandQueue->Release(); 
    device->Release(); 
    UnregisterClass(WindowClass, hInstance); 
    return 0; 
} 

я получаю следующие ошибки на линиях 97 и 102, соответственно:

The GPU device instance has been suspended. Use GetDeviceRemovedReason to determine the appropriate action. 

Вторая ошибка:

The GPU will not respond to more commands, most likely because some other application submitted invalid commands. 
The calling application should re-create the device and continue. 

ответ

1

Это кажется бросить курить скорее всего, будет ошибкой драйвера. Проверьте, нет ли обновленных драйверов для вашего оборудования. Вы должны попробовать использовать шаблоны игр Direct3D12 в этом VSIX и посмотреть, попадают ли они в тот же тип проблемы (более подробную информацию о шаблонах см. В разделе this blog post).

Ваш каскадный шаблон вызова D3D12CreateDevice для различных уровней детализации необычен и не нужен. Если ваше приложение может работать с Direct3D Feature Level 11.0 или выше, просто используйте D3D_FEATURE_LEVEL_11_0 один раз. Вы должны передать любой ваш минимальный поддерживаемый уровень функции для этой функции.

Если устройство Direct3D 12 не поддерживает более высокий уровень функций, вы можете обнаружить, что с помощью CheckFeatureSupport либо путем проверки отдельных функций или с помощью D3D12_FEATURE_FEATURE_LEVELS:

// Create the DX12 API device object. 
DX::ThrowIfFailed(D3D12CreateDevice(
    adapter.Get(), 
    m_d3dMinFeatureLevel, 
    IID_PPV_ARGS(&m_d3dDevice) 
    )); 

// Determine maximum supported feature level for this device 
static const D3D_FEATURE_LEVEL s_featureLevels[] = 
{ 
    D3D_FEATURE_LEVEL_12_1, 
    D3D_FEATURE_LEVEL_12_0, 
    D3D_FEATURE_LEVEL_11_1, 
    D3D_FEATURE_LEVEL_11_0, 
}; 

D3D12_FEATURE_DATA_FEATURE_LEVELS featLevels = 
{ 
    _countof(s_featureLevels), s_featureLevels, D3D_FEATURE_LEVEL_11_0 
}; 

HRESULT hr = m_d3dDevice->CheckFeatureSupport(D3D12_FEATURE_FEATURE_LEVELS, 
    &featLevels, sizeof(featLevels)); 
if (SUCCEEDED(hr)) 
{ 
    m_d3dFeatureLevel = featLevels.MaxSupportedFeatureLevel; 
} 
else 
{ 
    m_d3dFeatureLevel = m_d3dMinFeatureLevel; 
} 

Имейте в виду, что D3D_FEATURE_LEVEL_12_0 и D3D_FEATURE_LEVEL_12_1 являются по существу только D3D_FEATURE_LEVEL_11_1 с несколькими дополнительными функциями, обязательными. Если ваше приложение уже проверяет их на 11.x, тогда нет причин «требовать» 12.0 или 12.1. См. MSDN.

Для подавляющего большинства игр Direct3D 12 & приложений, D3D_FEATURE_LEVEL_11_0 или D3D_FEATURE_LEVEL_11_1 являются хорошим выбором. Имейте в виду, что в то время как AMD/ATI поддерживала функцию Level 11.1 довольно рано, части NVIDIA DirectX 11 поддерживали только 11.0 с некоторыми дополнительными функциями в течение некоторого времени.

+0

Мое рассуждение с деревом if заключалось в том, что более новые уровни функций могут иметь лучшую поддержку драйверов, чем прежние уровни, поэтому они могут немного улучшиться. Пример, который вы дали, я теперь пытаюсь понять, почему он работает, а мой - нет. – Mikemk

+0

Устройство такое же независимо от того, какой уровень качества вы запрашиваете. Единственная причина, по которой вам хотелось бы знать, поддерживает ли устройство более высокий уровень производительности, - это то, что ваше приложение может использовать функции API, которые этого требуют. Об этом говорит проверка 'CheckFeatureSupport''. –