编程语言
首页 > 编程语言> > c# – 从CUDA更新D3D9纹理

c# – 从CUDA更新D3D9纹理

作者:互联网

我正在研究一个原型,它集成了WPF,Direct3D9(使用微软的D3DImage WPF类)和CUDA(我需要能够为GPU上的D3DImage生成纹理).

问题是,CUDA不会更新我的纹理.没有返回错误代码,纹理保持不变.即使我在自己的写作之后阅读,我也看不到任何变化.如何更新我的D3D9纹理?

我甚至没有运行任何CUDA内核,出于调试目的,我只使用cuMemcpy2D API通过从CPU复制一些伪数据来编写CUDA内存.

这是代码,它是C#,但我在评论中放置了原生API:

static void updateTexture( Texture tx )
{
    var size = tx.getSize();

    using( CudaDirectXInteropResource res = new CudaDirectXInteropResource( tx.NativePointer, CUGraphicsRegisterFlags.None, CudaContext.DirectXVersion.D3D9 ) )  // cuGraphicsD3D9RegisterResource
    {
        res.Map();  // = cuGraphicsMapResources
        using( CudaArray2D arr = res.GetMappedArray2D( 0, 0 ) ) // cuGraphicsSubResourceGetMappedArray, cuArrayGetDescriptor. The size is correct here, BTW
        {
            // Debug code below - don't run any kernels for now, just call cuMemcpy2D to write the GPU memory
            uint[] arrWhite = new uint[ size.Width * size.Height ];
            for( int i = 0; i < arrWhite.Length; i++ )
                arrWhite[ i ] = 0xFF0000FF;
            arr.CopyFromHostToThis( arrWhite ); // cuMemcpy2D

            uint[] test = new uint[ size.Width * size.Height ];
            arr.CopyFromThisToHost( test ); // The values here are correct
        }
        res.UnMap(); // cuGraphicsUnmapResources
    }
    tx.AddDirtyRectangle();

    // Map again and check what's in the resource
    using( CudaDirectXInteropResource res = new CudaDirectXInteropResource( tx.NativePointer, CUGraphicsRegisterFlags.None, CudaContext.DirectXVersion.D3D9 ) )
    {
        res.Map();
        using( CudaArray2D arr = res.GetMappedArray2D( 0, 0 ) )
        {
            uint[] test = new uint[ size.Width * size.Height ];
            arr.CopyFromThisToHost( test ); // All zeros :-(
            Debug.WriteLine( "First pixel: {0:X}", test[ 0 ] );
        }
        res.UnMap();
    }
}

解决方法:

正如评论者所暗示的那样,我尝试创建一个CudaDirectXInteropResource实例以及D3D纹理.
有效.

这是反直觉的,没有文档记录,但看起来像cuGraphicsUnregisterResource会破坏新写入的数据.
至少在我的机器上使用GeForce GTX 960,Cuda 7.0和Windows 8.1 x64.

所以,解决方案 – 每个纹理调用一次cuGraphicsD3D9RegisterResource,并使用cuGraphicsMapResources / cuGraphicsUnmapResources API来允许CUDA访问纹理数据.

标签:c,cuda,sharpdx,direct3d9,managed-cuda
来源: https://codeday.me/bug/20190623/1273685.html