accessing DXVA NV12 surfaces

Hey guys,

I’m trying to access a DXVA NV12 IDirect3D9Surface via CUDA like this:

void TestDxvaCudaInterop(IDirect3DDevice9* d3d9Device)
  IDirectXVideoProcessorService* dxvaProcessorService = NULL;
  IDirect3DSurface9* nv12Surface = NULL;
  CUcontext cudaContext;
  CUdevice cudaDevice;
  CUgraphicsResource nv12cuda;

  cuD3D9CtxCreate(&cudaContext, &cudaDevice, CU_CTX_SCHED_BLOCKING_SYNC, d3d9Device);
  DXVA2CreateVideoService(d3d9Device, __uuidof(IDirectXVideoProcessorService), (void **) &dxvaProcessorService);
  dxvaProcessorService->CreateSurface(256, 256, 0, (D3DFORMAT) MAKEFOURCC('N', 'V', '1', '2'), D3DPOOL_DEFAULT, 0, DXVA2_VideoProcessorRenderTarget, &nv12Surface, NULL);
  if ((nv12Surface) && (cuGraphicsD3D9RegisterResource(&nv12cuda, nv12Surface, CU_GRAPHICS_REGISTER_FLAGS_NONE) == CUDA_ERROR_INVALID_HANDLE))
    MessageBox(0, "invalid handle", "error", 0);

Unfortunately that doesn’t work (CUDA_ERROR_INVALID_HANDLE), at least not on my current development system:

win7 x64, 9400 mainboard, driver 306.23, cuda 5.0.1 driver

Does anybody know a way to make this work? FWIW, I know that I could transfer the data to CPU RAM, then back to GPU RAM, to work around the problem, but that’s not really acceptable due to performance reasons. I know I could also convert the NV12 surface to RGB, but that’s not acceptable, either, because I want to run my own algorithms for chroma upsampling and color conversion.

FWIW, I can access DXVA NV12 surfaces just fine with AMD GPUs, using the latest beta drivers and the OpenCL 1.2 D3D9 interop extension.


DXVA Checker is a small and very easy to use application that will provide you with various information about your Decoder Device and Processor Device that can be used with GPU. Check that your device supports the format you want.