Я пытаюсь написать функции для преобразования текстуры OpenGL в тензор PyTorch и обратно в приложении C++. Чтобы проверить, работает ли это, я добавил к тензору 128, чтобы сделать изображение ярче, а затем отрендерил полученную текстуру в квадрате. В основном это работает, но у меня наблюдается странное поведение, при котором часть текстуры не затрагивается.
это оригинальная текстура, и — это текстура после добавления 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));
}
Кто-нибудь знает, что может быть причиной этого? Я ошибся с размерами буферов и массивов?
В CUDA не поддерживаются 3-байтовые пиксели изображения. Пытаться
size_t size = width * height * 4 * sizeof(unsigned char);
Это выдержка из документов: