CUDA (Libtorch) 和 OpenGL 互操作的奇怪行为

问题描述 投票:0回答:1

我正在尝试编写函数来将 OpenGL 纹理转换为 PyTorch 张量并在 C++ 应用程序中转换回来。为了测试它是否有效,我向张量添加了 128 以基本上使图像变亮,然后在四边形上渲染生成的纹理。它大部分有效,但我遇到了一种奇怪的行为,其中部分纹理不受影响。

This 是原始纹理,并且 this 是对张量中的每个元素添加 128 后的纹理。请注意,像 1/4 的图像不受此操作影响

这些是相关的代码部分。

textureColorbuffer
使用 GL_RGB 格式(如果我理解正确的话,每个通道的位深度为 8)。这是我调用函数并添加到张量的地方:

cudaGraphicsGLRegisterImage(&cudaResource, textureColorbuffer, GL_TEXTURE_2D, cudaGraphicsMapFlagsNone);
torch::Tensor tensor = resourceToTensor(cudaResource, WIDTH, HEIGHT);
tensor = tensor + static_cast<unsigned char>(128);
tensorToResource(tensor, cudaResource, WIDTH, HEIGHT);

使用的功能如下:

torch::Tensor resourceToTensor(cudaGraphicsResource* cudaResource, int width, int height) {
    CUDA_CHECK_ERROR(cudaGraphicsMapResources(1, &cudaResource, 0));
    cudaArray* textureArray;
    CUDA_CHECK_ERROR(cudaGraphicsSubResourceGetMappedArray(&textureArray, cudaResource, 0, 0));

    unsigned char* devicePtr;
    size_t size = width * height * 3 * sizeof(unsigned char);
    CUDA_CHECK_ERROR(cudaMalloc(&devicePtr, size));

    CUDA_CHECK_ERROR(cudaMemcpyFromArray(devicePtr, textureArray, 0, 0, size, cudaMemcpyDeviceToDevice));
    auto options = torch::TensorOptions().dtype(torch::kUInt8).device(torch::kCUDA);
    torch::Tensor tensor = torch::from_blob(devicePtr, { height, width, 3 }, options);

    CUDA_CHECK_ERROR(cudaGraphicsUnmapResources(1, &cudaResource, 0));

    torch::Tensor clonedTensor = tensor.clone();

    CUDA_CHECK_ERROR(cudaFree(devicePtr));
    return clonedTensor;
}

void tensorToResource(torch::Tensor tensor, cudaGraphicsResource* cudaResource, int width, int height) {
    tensor = tensor.to(torch::kCUDA);

    CUDA_CHECK_ERROR(cudaGraphicsMapResources(1, &cudaResource, 0));
    cudaArray* textureArray;
    CUDA_CHECK_ERROR(cudaGraphicsSubResourceGetMappedArray(&textureArray, cudaResource, 0, 0));

    const unsigned char* devicePtr = tensor.data_ptr<unsigned char>();
    size_t size = width * height * 3 * sizeof(unsigned char);
    CUDA_CHECK_ERROR(cudaMemcpyToArray(textureArray, 0, 0, devicePtr, size, cudaMemcpyDeviceToDevice));

    CUDA_CHECK_ERROR(cudaGraphicsUnmapResources(1, &cudaResource, 0));
}

有人知道这可能是什么原因吗?我是否在缓冲区和数组的大小上犯了错误?

c++ opengl cuda libtorch
1个回答
0
投票

在 CUDA 中,不支持 3 字节图像像素。尝试一下

size_t size = width * height * 4 * sizeof(unsigned char);

这是文档的摘录: CUDA docs

© www.soinside.com 2019 - 2024. All rights reserved.