Is CUDA - OpenGL possible with a shared OpenGL context?

In our application, we are successfully using CUDA OpenGL interop. Our application uses some GLSL shaders to write into a texture (via a frame buffer) and subsequently reads the data from the texture in a CUDA kernel.

For performance reasons, we are moving to an asynchronous architecture. In this architecture, thread A writes the texture in OpenGL context A. Subsequently, we pass on the texture to thread B using OpenGL context B, which is shared with OpenGL context A.

This is what we do in pseudo-code:

void ApixaThread::run()
{
    if (!m_context->makeCurrent(m_surface.get()))
    {
        Log::error("Failed to make the shared OpenGL context current to the Apixa thread.");
        return;
    }

    if (!InitCuda())
    {
        Log::error("Failed to initialize CUDA for the Apixa thread.");
        return;
    }

    while (!isInterruptionRequested())
    {
        Input input = GetNextFromQueue();

        GLuint tex_name = input.tpeIn->GetTextureID();
        glBindTexture(GL_TEXTURE_2D, tex_name);
        if (!OpenGLUtil::IsOpenGLSucces())
        {
            Log::info("Failed to bind texture");
            continue;
        }

        if (!MapOpenGlTextureInCuda(input.tpeIn))
        {
            Log::error("Failed to map and OpenGL texture in CUDA: id={} is-texture={}", textureName, glIsTexture(tex_name));
            continue;
        }
    }
}

bool InitCuda(int deviceIndex = 0)
{
    CUresult cudaResult;

    CUdevice cuDevice {};
    cudaResult = cuDeviceGet(&cuDevice, deviceIndex);
    if (cudaResult != CUDA_SUCCESS)
    {
        Log::error("Failed query the CUDA device with index {}: {}", deviceIndex, FmtCudaError(cudaResult));
        return false;
    }

    char deviceNameBuffer[128] { 0 };
    cudaResult = cuDeviceGetName(deviceNameBuffer, 128, cuDevice);
    if (cudaResult != CUDA_SUCCESS)
    {
        Log::error("Failed to query the device name: {}", FmtCudaError(cudaResult));
        return false;
    }

    CUcontext cudaContext {};
    cudaResult = cuCtxCreate(&cudaContext, 0, cuDevice);
    if (cudaResult != CUDA_SUCCESS)
    {
        Log::error("Failed to create a new CUDA context: {}", FmtCudaError(cudaResult));
        return false;
    }

    cudaResult = cuCtxSetCurrent(cudaContext);
    if (cudaResult != CUDA_SUCCESS)
    {
        Log::error("Failed to make the CUDA context current: {}", FmtCudaError(cudaResult));
        return false;
    }

    Log::info("Successfully initialized CUDA device '{}', index {}", deviceNameBuffer, deviceIndex);
    return true;
}

bool MapOpenGlTextureInCuda(const PooledTextureRef& tpe)
{
    CUresult error;

    CUgraphicsResource m_pcudaResource;
    error = cuGraphicsGLRegisterImage(&m_pcudaResource, tpe->GetTextureID(), GL_TEXTURE_2D, CU_GRAPHICS_REGISTER_FLAGS_READ_ONLY);
    if (error != CUDA_SUCCESS)
    {
        Log::error("Failed to register texture to CUDA: {}", FmtCudaError(error));
        return false;
    }

    return true;
}

It would be great if someone could tell me if CUDA—OpenGL interop is possible with a shared texture or if this is already a losing strategy. I couldn’t find anything in the documentation that says this would not be possible.

Thanks,
Thomas