nvEncRegisterResource failed with D3D9 Texture or D3D9 RenderTarget

I try to modify the NvEncoderD3DInterop example in Nvidia Video_Codec_SDK_7.0.1. The example code is use DXVA2 to create surface, and then call nvEncRegisterResource to do register, it success and the returned registeredResource is not zero. But i want use D3D9 to create texture surface or rendertarget surface, but it failed to do register, the nvEncRegisterResource return NV_ENC_SUCCESS, but the returned registeredResource is zero. I don’t know why, can someone help me? Many Thanks. Here is my example code.

IDirect3DSurface9* pSurface = NULL;
//hr = m_pD3D9Device->CreateRenderTarget(uInputWidth, uInputHeight, D3DFMT_X8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &pSurface, NULL);
IDirect3DTexture9 *pText = NULL;
hr = m_pD3D9Device->CreateTexture(uInputWidth, uInputHeight, 0, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pText, NULL);
hr = pText->GetSurfaceLevel(0, &pSurface);

nvStatus = m_pNvHWEncoder->NvEncRegisterResource(NV_ENC_INPUT_RESOURCE_TYPE_DIRECTX, (void*)pSurface/pVPSurfaces[i]/,
uInputWidth, uInputHeight, uInputWidth*4/m_stEncodeBuffer[i].stInputBfr.uRGBStride/, &m_stEncodeBuffer[i].stInputBfr.nvRegisteredResource);
if (nvStatus != NV_ENC_SUCCESS)
return nvStatus;

Here return NV_ENC_SUCCESS, but nvRegisteredResource is zero.


I hit this same issue. The only type of buffer I’ve found that doesn’t give a null .registeredResource is an offscreen plain surface. A render target surface, or level 0 surface of a texture (whether render target or not) all give a null .registeredResource (which will cause an error if you try and use).

What’s worse is that D3D9 has no method of copying to an offscreen plain surface, unless it is created in system memory instead of video memory. Using system memory makes the whole thing pointless. I need to encode from video memory directly. NVFBC captures to an offscreen plain surface, so that works with NVENC, but the current NVENC API appears useless for encoding any other video memory.

I tried passing a D3D11 device and surface but this caused NvEncRegisterResource to crash in d3d11.dll.

Anybody know of other surfaces types (even if different D3D version) that NvEncRegisterResource will accept?

(K3000M, initially 362.77 driver, updated to latest 376.33 with same result, Video Codec SDK 7.1.9 on Windows 7)

Thanks to help from Osurac I got this working using by passing a D3D11Texture2D and setting .bufferFormat:

ID3D11Texture2D *pD3D11Texture;
        .version = NV_ENC_REGISTER_RESOURCE_VER,
        .resourceToRegister = (void*)pD3D11Texture,
        .width = 1920,
        .height = 1080,
        .bufferFormat = NV_ENC_BUFFER_FORMAT_ARGB,