2011-09-02 91 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有特定的要求)。