代码之家  ›  专栏  ›  技术社区  ›  asmo_192

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

  •  0
  • asmo_192  · 技术社区  · 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));
    }
    

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

    1 回复  |  直到 1 年前
        1
  •  0
  •   Dmitry Negoda    1 年前

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

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

    这是文档摘录: CUDA docs