【问题标题】:DirectX 11 IDXGISwapChain::GetBuffer failing with DXGI_ERROR_INVALID_CALLDirectX 11 IDXGISwapChain::GetBuffer 因 DXGI_ERROR_INVALID_CALL 而失败
【发布时间】:2014-04-24 21:47:50
【问题描述】:

我正在 DirectX11 中创建一个设备和交换链,然后尝试获取后台缓冲区的纹理。创建步骤似乎有效,但无论我做什么,GetBuffer 调用总是失败并出现错误 DXGI_ERROR_INVALID_CALL (887a0001)。 下面是创建设备的代码:

    D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_9_1 };
    int numFeatureLevels = sizeof(featureLevels) / sizeof(featureLevels[0]);
    DXGI_SWAP_CHAIN_DESC swapChainDesc;
    ID3D11Device* pDevice;
    IDXGISwapChain* pSwapChain;
    D3D_FEATURE_LEVEL featureLevel;
    ID3D11DeviceContext* pContext;

    swapChainDesc.Windowed = TRUE;
    swapChainDesc.OutputWindow = (HWND)(void*)pWindowHandle;
    swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_SEQUENTIAL;
    swapChainDesc.SampleDesc.Count = 1;
    swapChainDesc.SampleDesc.Quality = 0;
    swapChainDesc.BufferCount = 2;
    swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    swapChainDesc.BufferDesc.Width = 0;
    swapChainDesc.BufferDesc.Height = 0;
    swapChainDesc.BufferDesc.RefreshRate.Numerator = 1;
    swapChainDesc.BufferDesc.RefreshRate.Denominator = 60;
    swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
    swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
    swapChainDesc.BufferUsage = DXGI_USAGE_SHADER_INPUT|DXGI_USAGE_RENDER_TARGET_OUTPUT;
    swapChainDesc.Flags = 0;

    err = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, D3D11_CREATE_DEVICE_DEBUG, featureLevels, numFeatureLevels, D3D11_SDK_VERSION,
        &swapChainDesc, &pSwapChain, &pDevice, &featureLevel, &pContext);

    if (!SUCCEEDED(err))
    {
        printf("D3D11CreateDeviceAndSwapChain failed with error %08x\n", err);
        return false;
    }

    m_pDevice = pDevice;
    m_pSwapChain = pSwapChain;
    m_pDeviceContext = pContext;
    m_featureLevel = featureLevel;

    ID3D11Texture2D* pTex = NULL;
    err = m_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)pTex);
    if (!SUCCEEDED(err))
    {
        printf("GetBuffer failed with error %08x\n", err);
        return false;
    }

这是托管 C++,它被编译成 DLL 并从 C# 控件的 OnCreateControl 方法运行,该方法将 Handle 作为 pWindowHandle 传递给函数。

创建设备调用成功,给我 FEATURE_LEVEL_11_0,但第二个 printf 函数总是打印错误 887a0001。使用参考设备无济于事。我正在链接 d3dx11.lib、d3d11.lib、dxgi.lib、dxguid.lib、d3dcompiler.lib、d3d10.lib 和 d3dx10.lib。 我尝试用 IID_ID3D11Texture2D 替换 __uuidof 并没有什么区别。 我在 Windows 7 上使用 Visual Studio Express 2013 for Windows Desktop 和 Microsoft DirectX SDK(2010 年 6 月)。所有 x86 和 x64、调试和发布版本都存在同样的问题。我启用详细调试输出的尝试也失败了;我试图通过控制面板中的 DirectX 属性强制它打开,将我的程序添加到可执行文件列表中,但在运行时没有打印任何额外内容。

【问题讨论】:

    标签: c++ directx-11 managed-c++


    【解决方案1】:

    您刚刚错误地传递了最后一个参数。而不是这个:

    err = m_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)pTex);
    

    你应该传递一个指向接口指针的指针,像这样:

    err = m_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&pTex);
                                                                        ^
                                                                        |
    

    【讨论】:

    • 这当然是完全正确的。我已经盯着那个代码好几天了,没有发现。谢谢!
    • 使用IID_PPV_ARGS 宏来避免这种确切情况(C 样式转换为void)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多