CUDA and Direct3D interoperability in WPF applications cudaGraphicsD3D9RegisterResource function ret

Hi folks,

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”

I works, I see a rotating triangle.

  1. 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));

	printf("> Adapter: %d\n", 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:

[i]NVIDIA GTX 260 800 MB

NVIDIA GTX 460 2 GB

CUDA 4.0

Windows 7 64-bit

8GB RAM

Visual Studio 2010

[/i]

Best regards,

Vitaliy

If you’re using cutilCheckMsg, I think you should be wrapping the other calls in cutilSafeCall – otherwise the message won’t be shown, even if an error has occurred.

So this:

cudaGraphicsD3D9RegisterResource(&positionsVB_CUDA, m_pd3dVB, cudaGraphicsRegisterFlagsNone);

cutilCheckMsg("cudaGraphicsD3D9RegisterResource failed");

cudaGraphicsResourceSetMapFlags(positionsVB_CUDA, cudaGraphicsMapFlagsWriteDiscard);

Should be this:

cutilSafeCall(cudaGraphicsD3D9RegisterResource(&positionsVB_CUDA, m_pd3dVB, cudaGraphicsRegisterFlagsNone));

cutilCheckMsg("cudaGraphicsD3D9RegisterResource failed");

cutilSafeCall(cudaGraphicsResourceSetMapFlags(positionsVB_CUDA, cudaGraphicsMapFlagsWriteDiscard));

That doesn’t answer your question, but maybe give it a try and see if there’s an error thrown somewhere which was otherwise being missed.