cudaGraphicsGLRegisterImage (..) возвращает cudaErrorUnknown; Каковы возможные источники ошибок? - PullRequest
0 голосов
/ 22 марта 2012

Я использую API времени выполнения CUDA. В коде хоста моего файла ядра я делаю следующее:

unsigned char* pData = new unsigned char[2*256*256*256]();

glTexImage3D(
  nTextureID, // created before (glBindTexture etc.)
  0, 
  nInternalFormat, // GL_LUMINANCE_ALPHA
  256, 
  256, 
  256, 
  0, 
  nDataFormat, // GL_LUMINANCE8_ALPHA8
  nDataType, // GL_UNSIGNED_BYTE
  pData);

/* ... still in OpenGL context ... */

cudaGraphicsResource* pGraphicResource = 0;
cudaError_t eError = cudaGraphicsGLRegisterImage(
  &pGraphicResource, 
  nTextureID, 
  GL_TEXTURE_3D, 
  cudaGraphicsRegisterFlagsSurfaceLoadStore);

Что бы я ни делал или изменял в отношении формата текстуры и / или типа данных, я всегда получаю cudaErrorUnknown для eError. Я не могу поверить, что ошибка вызвана неправильным форматом, потому что в официальной документации ( внешняя ссылка ) сказано, что все эти форматы поддерживаются.

Итак, мой вопрос к вам: какие еще причины может иметь cudaErrorUnknown в этом контексте?

Кстати: раньше я не использовал вызов cudaSetDevice или cudaGLSetGLDevice. При этом возникают проблемы с «Ошибка API времени выполнения: все устройства с поддержкой CUDA заняты или недоступны». Но я доказал, что индекс текущего устройства одинаков и действителен (мой Quadro 600) до и после вызова.

Мой графический процессор: NVIDIA Quadro 600 Мой SDK: Набор инструментов NVIDIA CUDA v4.1

Ответы [ 2 ]

1 голос
/ 24 марта 2012

Я думаю, что проблема (кроме странного () после вашего вызова new - какого черта это?) Заключается в том, что вы передаете идентификатор в качестве целевого параметра glTexImage3D:

unsigned char* pData = new unsigned char[2*256*256*256](); // note weird parens here

glTexImage3D(
  nTextureID, // created before (glBindTexture etc.)
  0, 
  nInternalFormat, // GL_LUMINANCE_ALPHA
  256, 
  256, 
  256, 
  0, 
  nDataFormat, // GL_LUMINANCE8_ALPHA8
  nDataType, // GL_UNSIGNED_BYTE
  pData);

Первый аргумент любого вызова glTexImage* - это цель, которая является значением enum, а не ID текстуры.То, что вы должны иметь, выглядит примерно так:

glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);

glTexImage3D(
  GL_TEXTURE_3D,
  0, 
  nInternalFormat, // GL_LUMINANCE_ALPHA
  256, 
  256, 
  256, 
  0, 
  nDataFormat, // GL_LUMINANCE8_ALPHA8
  nDataType, // GL_UNSIGNED_BYTE
  pData);

Так что я думаю, что это проблема OpenGL, а не проблема CUDA - если вы проверите ошибки GL, вы, вероятно, увидите ошибку недопустимого значения или что-то послеglTexImage3D звонок.Тот факт, что существует состояние ошибки GL, вероятно, объясняет, почему вы получаете cudaErrorUnknown.

1 голос
/ 22 марта 2012

Вот моя функция, которая готовит текстуру и затем регистрирует ее в CUDA.Может быть, это может вам помочь.

// Create a texture and register it for sharing with CUDA.
void CreateAndRegisterTex(GLuint& tex, cudaGraphicsResource*& resource, u32 w, u32 h) {
  u32 i(0);
  uchar4* buf((uchar4*)malloc(w * h * sizeof(uchar4)));
  glGenTextures(1, &tex);
  glBindTexture(GL_TEXTURE_2D, tex);
  // glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // program works without this but maybe it should be in there?
  glTexImage2D(GL_TEXTURE_2D, 0, 4, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, buf);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_REPEAT);
  glBindTexture(GL_TEXTURE_2D, 0);
  free(buf);
  glBindTexture(GL_TEXTURE_2D, tex);
  // Register this image for sharing with CUDA. cudaGraphicsGLRegisterImage()
  // supports all texture formats with 1, 2, or 4 components and an internal
  // type of float (e.g. GL_RGBA_FLOAT32) and unnormalized integer (e.g.
  // GL_RGBA8UI). It does not currently support normalized integer formats (e.g.
  // GL_RGBA8). Please note that since GL_RGBA8UI is an OpenGL 3.0 texture
  // format, it can only be written by shaders, not the fixed function pipeline.
  cutilSafeCall(cudaGraphicsGLRegisterImage(&resource, tex, GL_TEXTURE_2D,
                                            cudaGraphicsMapFlagsWriteDiscard));
}

Перед вызовом этой функции я звоню:

InitGL(&argc, argv));
g_cuda_device = cutGetMaxGflopsDeviceId();
cudaSetDevice(g_cuda_device);
cudaGLSetGLDevice(g_cuda_device);

При изменении устройства на другое, отличное от значения по умолчанию, я звоню:

GLDeviceInit(g_cuda_device);
...