Почему D3D11CreateDevice () начал генерировать исключения? - PullRequest
0 голосов
/ 24 апреля 2018

Недавно часть кода, которая раньше работала нормально, начала выдавать исключения. Соответствующая часть рассматриваемой функции:

HRESULT DC11::TryCreateDevice(
    _In_ IDXGIAdapter* pAdapter,
    D3D_DRIVER_TYPE driverType,
    UINT createDeviceFlags,
    _COM_Outptr_ ID3D11Device** ppDevice,
    _Out_opt_ UINT* pShaderModel,
    _COM_Outptr_ ID3D11DeviceContext** ppDeviceContext)
{
    UINT createDeviceFlags0 = 0;

#ifdef _DEBUG
    createDeviceFlags0 = D3D11_CREATE_DEVICE_DEBUG;
#endif

    if ((createDeviceFlags & createDeviceFlags0) != 0)
    {
        throw std::invalid_argument(
            "createDeviceFlags");
    }

    createDeviceFlags0 |= createDeviceFlags;

    SafeComPointer<ID3D11Device> device;

    SafeComPointer<ID3D11DeviceContext> deviceContext;

    D3D_FEATURE_LEVEL featureLevels[] =
    {
        D3D_FEATURE_LEVEL_11_1,
        D3D_FEATURE_LEVEL_11_0,
        D3D_FEATURE_LEVEL_10_1,
        D3D_FEATURE_LEVEL_10_0,
    };

    D3D_FEATURE_LEVEL featureLevel;

    HRESULT hr;

    hr = ::D3D11CreateDevice(
        pAdapter,
        driverType,
        nullptr,
        createDeviceFlags0,
        featureLevels,
        ARRAYSIZE(featureLevels),
        D3D11_SDK_VERSION,
        device.GetAddressOf(),
        &featureLevel,
        deviceContext.GetAddressOf());

....

Когда я нажимаю D3D11CreateDevice, я получаю

Unhandled exception at 0x00007ffff54b3ce0 in CryptoNightTester.exe: 0xC0000005: Access violation reading location 0xffffffffffffffff

, который предлагает мне винтовой указатель. Принимая во внимание, что этот раздел кода не изменился вообще между тем, когда он работал, и когда он не работал, мне было интересно, если что-то пошло не так с аргументами указателя. Я быстро подтвердил, что ppDevice и ppDeviceContext - то, чем они должны быть, поэтому я посмотрел на pAdapter.

В окрестностях телефонный код

SafeComPointer<IDXGIFactory1> factory;

CHR(CreateDXGIFactory1(
    __uuidof(IDXGIFactory1),
    reinterpret_cast<void**>(factory.GetAddressOf())));

SafeComPointer<IDXGIAdapter1> adapter;

HRESULT hr = factory->EnumAdapters1(
    0,
    adapter.GetAddressOf());

if (hr == DXGI_ERROR_NOT_FOUND)
{
    return false;
}

CHR(hr);

DXGI_ADAPTER_DESC1 adapterDesc1;

hr = adapter->GetDesc1(&adapterDesc1);

FullHash mainLoopHasher;

mainLoopHasher.Create(
    adapter,
    5);

...

void FullHash::Create(
    _Inout_ SafeComPointer<IDXGIAdapter1>& adapter,
    _In_ uint32_t shaderModel)
{
    this->adapter.Swap(adapter);

    this->shaderModel = shaderModel;

    this->SetupShader();
}


void FullHash::SetupShader()
{
    UINT createDeviceFlags =
        D3D11_CREATE_DEVICE_SINGLETHREADED;

    bool deviceCreated = false;

#ifdef _DEBUG
    // try to enable performance counters
    createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUGGABLE;

    deviceCreated = DC11::TryCreateDevice(
        this->adapter.Get(),
        D3D_DRIVER_TYPE_UNKNOWN,
        createDeviceFlags,
        this->device.GetAddressOf(),
        nullptr,
        this->deviceContext.GetAddressOf()) == S_OK;

....

, который впоследствии подтвердил (насколько я могу судить, во всяком случае), что адаптер должен быть таким. Следующее, что я протестировал, было то, что происходит, когда я заменяю pAdapter на NULL в D3D11CreateDevice. Это больше не вызывало исключение, но hr был теперь E_INVALIDARG.

В этот момент я немного застрял. Мое текущее предположение - недавно установленное / неустановленное программное обеспечение. Возможно, мне нужно переустановить SDK или драйвер или что-то? Я решил опубликовать здесь, прежде чем идти по этому пути, так как моя система смехотворно привередлива, когда дело доходит до установки драйверов графического процессора, поэтому то, что обычно является ранним средством, должно быть последним средством.

Для справки, я работаю над MSVS 2015 и имею Windows 10.

Редактировать: расширен код вызова

...