WPF应用程序中的CUDA和Direct3D互操作性

时间:2011-09-02 12:45:41

标签: wpf cuda directx direct3d

我尝试使用CUDA计算和Direct3D 9图形实现WPF应用程序。所以我使用以下方法:

  1. 我使用MSDN "Walkthrough: Hosting Direct3D9 Content in WPF"
  2. 创建WPF应用程序
  3. 然后我使用MSDN "Walkthrough: Creating Direct3D9 Content for Hosting in WPF"
  4. 创建DLL
  5. 它有效,我看到一个旋转的三角形。
  6. 然后我尝试按照3.2.11.2部分实现Direct3D 9互操作 “NVIDIA CUDA C编程指南”。但 cudaGraphicsD3D9RegisterResource函数返回错误。
  7. 我在类中声明了CUDA图形资源变量:

    #pragma once
    
    class CTriangleRenderer : public CRenderer
    {
    public:
        static HRESULT Create(IDirect3D9 *pD3D, IDirect3D9Ex *pD3DEx, HWND hwnd, UINT uAdapter, CRenderer **ppRenderer);
        ~CTriangleRenderer();
    
        HRESULT Render();
    
    protected:
        HRESULT Init(IDirect3D9 *pD3D, IDirect3D9Ex *pD3DEx, HWND hwnd, UINT uAdapter);
    
    private:
        CTriangleRenderer();
    
        IDirect3DVertexBuffer9 *m_pd3dVB;
        struct cudaGraphicsResource* positionsVB_CUDA;
    };
    

    cudaGraphicsD3D9RegisterResource 函数调用是此类成员:

    HRESULT 
    CTriangleRenderer::Init(IDirect3D9 *pD3D, IDirect3D9Ex *pD3DEx, HWND hwnd, UINT uAdapter)
    {
        HRESULT hr = S_OK;
        D3DXMATRIXA16 matView, matProj;
        D3DXVECTOR3 vEyePt(0.0f, 0.0f,-5.0f);
        D3DXVECTOR3 vLookatPt(0.0f, 0.0f, 0.0f);
        D3DXVECTOR3 vUpVec(0.0f, 1.0f, 0.0f);
    
        // Call base to create the device and render target
        IFC(CRenderer::Init(pD3D, pD3DEx, hwnd, uAdapter));
    
        // Set up the VB
        CUSTOMVERTEX vertices[] =
        {
            { -1.0f, -1.0f, 0.0f, 0xffff0000, }, // x, y, z, color
            {  1.0f, -1.0f, 0.0f, 0xff00ff00, },
            {  0.0f,  1.0f, 0.0f, 0xff00ffff, },
        };
    
        IFC(m_pd3dDevice->CreateVertexBuffer(sizeof(vertices), 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &m_pd3dVB, NULL));
    
        cudaGraphicsD3D9RegisterResource(&positionsVB_CUDA, m_pd3dVB, cudaGraphicsRegisterFlagsNone);
    
        cutilCheckMsg("cudaGraphicsD3D9RegisterResource failed");
    
        cudaGraphicsResourceSetMapFlags(positionsVB_CUDA, cudaGraphicsMapFlagsWriteDiscard);
    
        void *pVertices;
        IFC(m_pd3dVB->Lock(0, sizeof(vertices), &pVertices, 0));
        memcpy(pVertices, vertices, sizeof(vertices));
        m_pd3dVB->Unlock();
    
        // Set up the camera
        D3DXMatrixLookAtLH(&matView, &vEyePt, &vLookatPt, &vUpVec);
        IFC(m_pd3dDevice->SetTransform(D3DTS_VIEW, &matView));
        D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI / 4, 1.0f, 1.0f, 100.0f);
        IFC(m_pd3dDevice->SetTransform(D3DTS_PROJECTION, &matProj));
    
        // Set up the global state
        IFC(m_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE));
        IFC(m_pd3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE));
        IFC(m_pd3dDevice->SetStreamSource(0, m_pd3dVB, 0, sizeof(CUSTOMVERTEX)));
        IFC(m_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX));
    
    Cleanup:
        return hr;
    }
    

    positionVB_CUDA变量值在 cudaGraphicsD3D9RegisterResource 调用之前为0xcdcdcdcd且后面的值相同。

    我的错误在哪里?来自CUDA SDK的Direct3D 9互操作示例工作正常。我的配置:

    • NVIDIA GTX 260 800 MB
    • NVIDIA GTX 460 2 GB
    • CUDA 4.0
    • Windows 7 64位
    • 8GB RAM
    • Visual Studio 2010

1 个答案:

答案 0 :(得分:2)

CUDA对可以绑定的VB类型有特定要求(我认为你不能CPU锁定/解锁绑定到CUDA的VB)。 如果要修复锁定/解锁:打开DirectX错误日志记录并通过DirectX控制面板使用DirectX调试Dll(在启动菜单的DirectX文件夹中找到它(必须安装DirectX SDK))。这将启用DirectX的调试登录,这在调查DirectX错误时非常有用且信息丰富(它在Visual Studio中记录到输出窗口)。您可能试图锁定可解锁的VB(如果您希望从CPU可读,则有初始化VB的特定要求)。