2011-09-02 191 views
3

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

  1. 我创建使用MSDN "Walkthrough: Hosting Direct3D9 Content in WPF"
  2. 然后,我创建DLL使用MSDN "Walkthrough: Creating Direct3D9 Content for Hosting in WPF"
  3. 它的工作原理,我看到一个旋转的三角形WPF应用程序。
  4. 然后根据“NVIDIA CUDA C编程指南”的3.2.11.2部分的 ,尝试实现Direct3D 9 interop。但是 cudaGraphicsD3D9RegisterResource函数返回错误。

我宣布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; 
} 

positionsVB_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中

回答

2

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