为什么ID3D11Device的CreateDevice()返回错误0x80070057:“参数不正确”?

问题描述 投票:0回答:1

我正在尝试学习如何使用D3D11(我无论如何都不是图形编程的专业人士),并且在我的代码中的设备创建功能期间,它返回

E_INVALIDARG

#include <Windows.h>
#include <iostream>
#include <d3d11.h>
#include <dxgi.h>
#include <d3dcompiler.h>

#pragma comment(lib,"d3d11.lib")
#pragma comment(lib,"dxgi.lib")
#pragma comment(lib,"d3dcompiler.lib")

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
    case WM_DESTROY:
        PostQuitMessage(0);
        break;

    default:
        return DefWindowProc(hwnd, msg, wParam, lParam);
    }

    return 0;
}

#define WndHeight 700
#define WndWidth 1000

HRESULT hres = 0;

void check(LPCWSTR str)
{
    if (hres != S_OK)
    {
        OutputDebugString(str);

        LPVOID errorMsg;
        FormatMessage(
            FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
            NULL,
            hres,
            0, // Default language
            (LPWSTR)&errorMsg,
            0,
            NULL
        );

        // Create a buffer to hold the formatted message
        wchar_t buffer[256];
        swprintf_s(buffer, L"Error 0x%X: %s", hres, (errorMsg ? static_cast<LPCWSTR>(errorMsg) : L"Unknown error"));

        // Output the message to the debugger
        OutputDebugString(buffer);

        // Free the allocated buffer
        LocalFree(errorMsg);

        DWORD lastError = GetLastError();
        FormatMessage(
            FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
            NULL,
            lastError,
            0, // Default language
            (LPWSTR)&errorMsg,
            0,
            NULL
        );

        // Create a buffer for the additional system information
        swprintf_s(buffer, L"Additional system information: %s", (errorMsg ? static_cast<LPCWSTR>(errorMsg) : L"Unknown error"));

        // Output the additional system information to the debugger
        OutputDebugString(buffer);

        // Free the allocated buffer
        LocalFree(errorMsg);

        exit(-1);
    }
}

int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
    _In_opt_ HINSTANCE hPrevInstance,
    _In_ LPWSTR    lpCmdLine,
    _In_ int       nCmdShow)
{
    HWND hwnd;
    {
        WNDCLASS wc;
        wc.cbClsExtra = 0;
        wc.cbWndExtra = 0;
        wc.hbrBackground = CreateSolidBrush(RGB(0, 0, 0));
        wc.hCursor = NULL;
        wc.hIcon = NULL;
        wc.hInstance = hInstance;
        wc.lpfnWndProc = WndProc;
        wc.lpszClassName = L"MainClass";
        wc.lpszMenuName = nullptr;
        wc.style = CS_HREDRAW | CS_VREDRAW;

        if (!RegisterClass(&wc))
        {
            OutputDebugString(L"Class Registreation Failed!");
        }

        hwnd = CreateWindow(L"MainClass", L"simple quad", WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU,
            CW_USEDEFAULT, CW_USEDEFAULT,
            WndHeight, WndWidth,
            NULL,
            NULL,
            hInstance,
            NULL);

        if (!hwnd)
        {
            OutputDebugString(L"Window Creation Failed!");
        }
    }

    ID3D11Device* device = nullptr;
    ID3D11DeviceContext* context = nullptr;
    D3D_FEATURE_LEVEL SSfeaturelvl[] = { D3D_FEATURE_LEVEL_11_0 };

    IDXGIFactory1* dxgiFactory = nullptr;
    {
        hres = CreateDXGIFactory1(IID_PPV_ARGS(&dxgiFactory));
        check(L"\nIDXGIFactory1 Creation Failed!\n");
    }

    IDXGIAdapter* adapter = nullptr;
    {
        hres = dxgiFactory->EnumAdapters(0, &adapter);
        check(L"\nIDXGIAdapter Creation Failed!\n");

        DXGI_ADAPTER_DESC adapterDesc = { 0 };
        adapter->GetDesc(&adapterDesc);

        OutputDebugString(L"\nGraphics device : ");
        OutputDebugString(adapterDesc.Description);
    }

    hres = D3D11CreateDevice(adapter, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, SSfeaturelvl, 1, D3D11_SDK_VERSION, &device, NULL, &context);
    check(L"\nID3D11Device Creation Failed!\n");

    IDXGISwapChain* swapchain = nullptr;
    {
        DXGI_MODE_DESC modeDesc = { 0 };
        modeDesc.Width = WndWidth;
        modeDesc.Height = WndHeight;

        modeDesc.Format = DXGI_FORMAT_UNKNOWN;

        modeDesc.RefreshRate.Numerator = 30;
        modeDesc.RefreshRate.Denominator = 1;

        modeDesc.Scaling = DXGI_MODE_SCALING_STRETCHED;

        modeDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;

        DXGI_SWAP_CHAIN_DESC desc = { 0 };
        desc.BufferCount = 2;
        desc.BufferDesc = modeDesc;
        desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
        desc.Flags = 0;
        desc.OutputWindow = hwnd;
        desc.SampleDesc.Count = 1;
        desc.SampleDesc.Quality = 0;
        desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
        desc.Windowed = TRUE;

        hres = dxgiFactory->CreateSwapChain(device, &desc, &swapchain);
        check(L"\nswapchain Creation Failed!\n");
    }

    ID3D11Buffer* vertexbuffer = nullptr;
    {
        int vertices[] = {
            //  X,    Y
               -500,  350,
               -500, -250,
                500, -250,
                500,  250
        };

        D3D11_BUFFER_DESC VBdesc = { 0 };
        VBdesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
        VBdesc.ByteWidth = sizeof(vertices);
        VBdesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ;
        VBdesc.MiscFlags = 0;
        VBdesc.StructureByteStride = 2 * sizeof(int);
        VBdesc.Usage = D3D11_USAGE_DEFAULT;

        D3D11_SUBRESOURCE_DATA VBdata = { 0 };
        VBdata.pSysMem = vertices;
        VBdata.SysMemPitch = 0;
        VBdata.SysMemSlicePitch = 0;

        hres = device->CreateBuffer(&VBdesc, &VBdata, &vertexbuffer);
        check(L"\nvertexbuffer Creation Failed!\n");
    }

    ID3D11Buffer* indexbuffer = nullptr;
    {
        int vertices[] = {
         // 1, 2, 3
            0, 1, 2,
            2, 3, 0
        };

        D3D11_BUFFER_DESC VBdesc = { 0 };
        VBdesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
        VBdesc.ByteWidth = sizeof(vertices);
        VBdesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ;
        VBdesc.MiscFlags = 0;
        VBdesc.StructureByteStride = 3 * sizeof(int);
        VBdesc.Usage = D3D11_USAGE_DEFAULT;

        D3D11_SUBRESOURCE_DATA VBdata = { 0 };
        VBdata.pSysMem = vertices;
        VBdata.SysMemPitch = 0;
        VBdata.SysMemSlicePitch = 0;

        device->CreateBuffer(&VBdesc, &VBdata, &indexbuffer);
        check(L"\nindexbuffer Creation Failed!\n");
    }

    ID3D11VertexShader* VertesShader = nullptr;
    ID3DBlob* vsBlob = nullptr;
    {
        hres = D3DCompileFromFile(L"shaders.hlsl", nullptr, nullptr, "vs_main", "vs_5_0", 0, 0, &vsBlob, 0);
        check(L"\nvsBlob Creation Failed!\n");

        hres = device->CreateVertexShader(vsBlob->GetBufferPointer(), vsBlob->GetBufferSize(), nullptr, &VertesShader);
        check(L"\nVertesShader Creation Failed!\n");
    }

    ID3D11PixelShader* pixelShader;
    ID3DBlob* psBlob = nullptr;
    {
        hres = D3DCompileFromFile(L"shaders.hlsl", nullptr, nullptr, "ps_main", "ps_5_0", 0, 0, &psBlob, 0);
        check(L"\npsBlob Creation Failed!\n");

        hres = device->CreatePixelShader(psBlob->GetBufferPointer(), psBlob->GetBufferSize(), nullptr, &pixelShader);
        check(L"\npixelShader Creation Failed!\n");
        psBlob->Release();
    }

    ID3D11InputLayout* IL = nullptr;
    {
        D3D11_INPUT_ELEMENT_DESC IEdesc[] =
        {
            {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
        };

        hres = device->CreateInputLayout(IEdesc, ARRAYSIZE(IEdesc), vsBlob->GetBufferPointer(), vsBlob->GetBufferSize(), &IL);
        check(L"\nID3D11InputLayout Creation Failed!\n");
    }
    
    ID3D11RenderTargetView* RTV = nullptr;
    {
        ID3D11Texture2D* d3d11FrameBuffer;
        hres = swapchain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&d3d11FrameBuffer);
        check(L"\ngetbuffer for RTV Failed!\n");

        hres = device->CreateRenderTargetView(d3d11FrameBuffer, 0, &RTV);
        check(L"\nID3D11RenderTargetView Creation Failed!\n");
        d3d11FrameBuffer->Release();
    }

    {
        context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
        context->IASetIndexBuffer(indexbuffer, DXGI_FORMAT_R32G32B32_SINT, 0);
        context->IASetInputLayout(IL);

        context->VSSetShader(VertesShader, NULL, NULL);
        context->PSSetShader(pixelShader, NULL, NULL);

        RECT winRect;
        GetClientRect(hwnd, &winRect);

        D3D11_VIEWPORT viewport = { 0 };
        viewport.TopLeftX = 0.0f;
        viewport.TopLeftY = 0.0f;
        viewport.Width = (FLOAT)(winRect.right - winRect.left);
        viewport.Height = (FLOAT)(winRect.bottom - winRect.top);
        viewport.MinDepth = 0.0f;
        viewport.MaxDepth = 0.0f;

        context->RSSetViewports(1, &viewport);

        context->OMSetRenderTargets(1, &RTV, NULL);
    }
    
    ShowWindow(hwnd, SW_SHOW);
    UpdateWindow(hwnd);

    MSG msg = { 0 };
    while (msg.message != WM_QUIT)
    {
        if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }

        context->DrawIndexed(6, 0, 0);

        swapchain->Present(1, 0);
    }

    return 0;
}

一开始我不明白为什么,但后来我将

IDXGIAdapter
参数更改为
NULL
并且函数通过了,但我觉得它应该第一次就可以工作。我想知道为什么会发生这种情况,以及如何使用
IDXGIAdapter
界面而不是
NULL

c++ directx-11 dxgi
1个回答
1
投票

您无法传递 DXGI 适配器参考 D3D_DRIVER_TYPE_HARDWARE,如记录的

如果将 pAdapter 参数设置为非 NULL 值,则还必须 将 DriverType 参数设置为 D3D_DRIVER_TYPE_UNKNOWN 值。如果 将 pAdapter 参数设置为非 NULL 值,并将 DriverType 设置为 D3D_DRIVER_TYPE_HARDWARE 值的参数,D3D11CreateDevice 返回 E_INVALIDARG 的 HRESULT。

所以,你必须这样做:

hres = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, SSfeaturelvl, 1, D3D11_SDK_VERSION, &device, NULL, &context);

或者这个:

hres = D3D11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, 0, SSfeaturelvl, 1, D3D11_SDK_VERSION, &device, NULL, &context);
© www.soinside.com 2019 - 2024. All rights reserved.