表面对象的未对齐错误(Cuda / OpenGL互操作)

时间:2014-10-28 22:43:42

标签: opengl cuda

我目前正在尝试在我的项目上互操作Cuda和OpenGL,但事实证明这是一项具有挑战性的任务。我目前正在使用以下代码:

GLuint _frameTextureGL;
cudaGraphicsResource_t _frameTextureCUDA;

void GLInit(){
  glEnable(GL_TEXTURE_2D);
  glGenTextures(1, &_frameTextureGL);

  glBindTexture(GL_TEXTURE_2D, _frameTextureGL);
  {
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, RES_X, RES_Y, 0, GL_RGBA, GL_FLOAT, NULL);
  }
  glBindTexture(GL_TEXTURE_2D, 0);

  CudaErrorCheck(cudaGraphicsGLRegisterImage(&_frameTextureCUDA, _frameTextureGL, GL_TEXTURE_2D, cudaGraphicsRegisterFlagsWriteDiscard));
}


void DrawFrame(){

  LaunchKernel();

  glBindTexture(GL_TEXTURE_2D, _frameTextureGL);
  {
    glBegin(GL_QUADS);
    {
      glTexCoord2f(0.0f, 0.0f);
      glVertex2f(0.0f, 0.0f);
      glTexCoord2f(1.0f, 0.0f);
      glVertex2f(1.0f, 0.0f);
      glTexCoord2f(1.0f, 1.0f);
      glVertex2f(1.0f, 1.0f);
      glTexCoord2f(0.0f, 1.0f);
      glVertex2f(0.0f, 1.0f);
    }
    glEnd();
  }
  glBindTexture(GL_TEXTURE_2D, 0);

  glFinish();
  glutPostRedisplay();
}



LaunchKernel(){

  CudaErrorCheck (cudaGraphicsMapResources(1, &_frameTextureCUDA));  //error happens here

  cudaArray_t frameCudaArray;
  CudaErrorCheck( cudaGraphicsSubResourceGetMappedArray(&frameCudaArray, _frameTextureCUDA, 0, 0));
  cudaResourceDesc frameCudaArrayResourceDesc;

  frameCudaArrayResourceDesc.resType = cudaResourceTypeArray;
  frameCudaArrayResourceDesc.res.array.array = frameCudaArray;

  cudaSurfaceObject_t frameCudaSurfaceObject;
  CudaErrorCheck( cudaCreateSurfaceObject(&frameCudaSurfaceObject, &frameCudaArrayResourceDesc));

  KernelFunction<< <(RES_X * RES_Y / CUDA_THREADS_PER_BLOCK) + 1, CUDA_THREADS_PER_BLOCK >> >( frameCudaSurfaceObject);

  CudaErrorCheck( cudaDestroySurfaceObject(frameCudaSurfaceObject));

  CudaErrorCheck( cudaGraphicsUnmapResources(1, &_frameTextureCUDA));
  cudaStreamSynchronize(0);

}

__global__ void KernelFunction(cudaSurfaceObject_t frameCudaSurfaceObject){

  const int maxIndex = RES_X * RES_Y;
  int idx = threadIdx.x + blockDim.x * blockIdx.x;

  if (idx > maxIndex) return;

  surf2Dwrite(make_float4(1.0f, 0.0f, 0.0f, 1.0f), frameCudaSurfaceObject, 0, 0);

  //surf2Dwrite(make_float4(1.0f, 0.0f, 0.0f, 1.0f), frameCudaSurfaceObject, (idx % RES_X) * 4, idx / RES_X);

}

问题是内核上的surf2Dwrite会导致我的代码的其他部分出错。

当代码处于当前状态时,我的项目会运行,但它没有显示任何内容(我认为这是正常的,因为我没有正确填充表面对象)。

但如果我改变我的X&amp; Y坐标到(0,0)以外的任何值(例如,通过取消注释最后一行)然后我在LaunchKernel函数的第一行得到“未对齐错误”。 (此错误仅显示在第二帧,而不是第一帧)

我的代码基于this other answer,所以我认为这部分是正确的。

1 个答案:

答案 0 :(得分:2)

Surface使用以字节为单位的坐标,而不是以元素为单位。对于float4,x坐标应为x * 16(或x * sizeof(float4)),而不是x * 4

surf2Dwrite(make_float4(1.0f, 0.0f, 0.0f, 1.0f), frameCudaSurfaceObject, 
            (idx % RES_X) * sizeof(float4), idx / RES_X);