WPF 应用程序中的 CUDA 和 Direct3D 互操作性
我尝试使用CUDA计算和Direct3D 9图形来实现WPF应用程序。所以我使用以下方法:
- 我使用 MSDN“演练:托管 Direct3D9”创建 WPF 应用程序 WPF 中的内容”
- 然后我使用 MSDN“演练:创建 Direct3D9”创建 DLL WPF 中托管的内容”
- 它有效,我看到一个旋转三角形。
- 然后我尝试根据第 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:
- I create WPF application using MSDN "Walkthrough: Hosting Direct3D9
Content in WPF" - Then I create DLL using MSDN "Walkthrough: Creating Direct3D9
Content for Hosting in WPF" - It works, I see a rotating triangle.
- 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
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).