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

发布于 2024-12-02 16:10:17 字数 3212 浏览 2 评论 0原文

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

  1. 我使用 MSDN“演练:托管 Direct3D9”创建 WPF 应用程序 WPF 中的内容”
  2. 然后我使用 MSDN“演练:创建 Direct3D9”创建 DLL WPF 中托管的内容”
  3. 它有效,我看到一个旋转三角形。
  4. 然后我尝试根据第 3.2.11.2 部分实现 Direct3D 9 互操作 《NVIDIA CUDA C 编程指南》。但 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;
}

cudaGraphicsD3D9RegisterResource调用之前,positionVB_CUDA变量值为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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

淡墨 2024-12-09 16:10:17

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

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文