Accessing a YUV external texture directly in CUDA on Android


I was trying to find a way to access a YUV external texture directly in CUDA on Android. My development platform is the NVIDIA Android TV.

So far, the only way I could get this to work was using PBOs in OpenGL ES and registering them in CUDA with cudaGraphicsGLRegisterBuffer. I can then get a plain pointer to the underlying PBO pixels using cudaGraphicsResourceGetMappedPointer.

glGenBuffers(1, &gInPBO);
    // PBO initialisation ...

    cudaResult = cudaGraphicsGLRegisterBuffer(&cudaInPBORes, gInPBO, 0);

    if (cudaResult == cudaSuccess) {
        cudaResult = cudaGraphicsMapResources(1, &cudaInPBORes, 0);
        if (cudaResult == cudaSuccess) {
            size_t bufLength = 0;
            cudaResult = cudaGraphicsResourceGetMappedPointer(
                &cudaInPBODevPtr, &bufLength, cudaInPBORes);
            if (cudaResult == CUDA_SUCCESS) {
                FLOG("cudaInPBODevPtr %p\n", cudaInPBODevPtr);
        cudaResult = cudaGraphicsUnmapResources(1, &cudaInPBORes, 0);

However, this is really clunky because the PBO can’t be YUV, it needs to be RGB(A). On the other hand, I have some CUDA code which works directly on YUV.

This means I’m making an RGB(A) texture out of the decoded YUV, then converting the RGB(A) to YUV (in CUDA), then processing it in CUDA in YUV, and then converting it back to an RGB(A) texture to be displayed on-screen with OpenGL ES.

It would be much more straightforward if there was a way to map a GL_TEXTURE_EXTERNAL_OES YUV texture directly into CUDA.

Is there one?