开发者

CUDA and Direct3D interoperability in WPF applications

I try to realize WPF application using CUDA calculations and Direct3D 9 graphics. So I use following approach:

  1. I create WPF application using MSDN "Walkthrough: Hosting Direct3D9 Content in WPF"
  2. Then I create DLL using MSDN "Walkthrough: Creating Direct3D9 Content for Hosting in WPF"
  3. It works, I see a rotating triangle.
  4. Then I try to realize Direct3D 9 interop according to part 3.2.11.2 of "NVIDIA CUDA C Programming Guide". But cudaGraphicsD3D9RegisterResource function returns error.

I declare CUDA graphics resource variable in class:

#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 function call is this class member:

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 variable value is 0xcdcdcdcd before cudaGraphicsD3D9RegisterResource call and the same value after.

Where is my error? Direct3D 9 interop example from CUDA SDK works fine. My configuration:

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


CUDA has specific requirements for the types of VB that can be bound (I don't think you can CPU lock/unlock a VB that is bound to CUDA). If you want to fix the Lock/Unlock: Turn on the DirectX error logging and use the DirectX debug Dlls via the DirectX Control Panel (find it in the DirectX folder in the startup menu (you must have the DirectX SDK installed)). This will enable the debug loggin for DirectX which is very helpful and informative when investigating DirectX errors (it logs to the output window in Visual Studio). You're probable trying to lock an unlockable VB (there are specific requirements for initializing a VB if you want it to be readable from the CPU).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜