c++ - CUDA/OGL 互操作崩溃

标签 c++ opengl cuda interop

我正在尝试设置一个 CUDA/GL 互操作示例。我在互联网上查了一下,所以我找到了一些教程,里面有一些有用的东西。

我想要的只是在 CUDA 中生成纹理并使用 OpenGL 绘制它。

我现在拥有的源代码每次运行我的 Macbook Pro 都会崩溃,所以我想如果有人能关注一下它,那将会非常有帮助。

    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <math.h>

    #ifdef _WIN32
    #  define WINDOWS_LEAN_AND_MEAN
    #  define NOMINMAX
    #  include <windows.h>
    #endif

    // OpenGL Graphics includes
    #include <GL/glew.h>
    #if defined (__APPLE__) || defined(MACOSX)
    #include <GLUT/glut.h>
    #else
    #include <GL/freeglut.h>
    #endif

    // includes, cuda
    #include <cuda_runtime.h>
    #include <cuda_gl_interop.h>

    // Utilities and timing functions
    #include <helper_functions.h>    // includes cuda.h and cuda_runtime_api.h
    #include <timer.h>               // timing functions

    // CUDA helper functions
    #include <helper_cuda.h>         // helper functions for CUDA error check
    #include <helper_cuda_gl.h>      // helper functions for CUDA/GL interop

    #include <vector_types.h>
     const unsigned int window_width  = 512;
     const unsigned int window_height = 512;
    GLuint viewGLTexture;
    cudaGraphicsResource_t viewCudaResource;

    void initGLandCUDA() {
         int argc = 0;
         char** argv = NULL;
         glutInit(&argc, argv);
         glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
         glutInitWindowSize(window_width, window_height);
         glutCreateWindow("CUDA GL Interop");

         glewInit();

         glEnable(GL_TEXTURE_2D);
         glGenTextures(1, &viewGLTexture);
         glBindTexture(GL_TEXTURE_2D, viewGLTexture);
         {
             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, 512, 512, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
         }
         glBindTexture(GL_TEXTURE_2D, 0);

         cudaGLSetGLDevice(gpuGetMaxGflopsDeviceId());
         cudaGraphicsGLRegisterImage(&viewCudaResource, viewGLTexture, GL_TEXTURE_2D,     cudaGraphicsRegisterFlagsWriteDiscard);
    }    


    __global__ void renderingKernel(cudaSurfaceObject_t image) {
         unsigned int x = blockIdx.x*blockDim.x + threadIdx.x;
         unsigned int y = blockIdx.y*blockDim.y + threadIdx.y;

         uchar4 color = make_uchar4(0.f, 0.f, 0.f, .3f);
         //if I write in 0, 0 and not x,y, the computer is not crashing, but there is no black pixel at 0,0
         surf2Dwrite(color, image, x, y, cudaBoundaryModeClamp);
    }


    void callCUDAKernel(cudaSurfaceObject_t image) {
         dim3 block(8, 1, 1);
         dim3 grid(8, 1, 1);
         renderingKernel<<< grid, block>>>(image);
    }

     void renderFrame() {
        cudaGraphicsMapResources(1, &viewCudaResource);
        {
            cudaArray_t viewCudaArray;
            checkCudaErrors(cudaGraphicsSubResourceGetMappedArray(&viewCudaArray, viewCudaResource, 0, 0));
            cudaResourceDesc viewCudaArrayResourceDesc;
            {
                viewCudaArrayResourceDesc.resType = cudaResourceTypeArray;
                viewCudaArrayResourceDesc.res.array.array = viewCudaArray;
            }
            cudaSurfaceObject_t viewCudaSurfaceObject;
            checkCudaErrors(cudaCreateSurfaceObject(&viewCudaSurfaceObject, &viewCudaArrayResourceDesc));

            callCUDAKernel(viewCudaSurfaceObject);

            checkCudaErrors(cudaDestroySurfaceObject(viewCudaSurfaceObject));
        }
        checkCudaErrors(cudaGraphicsUnmapResources(1, &viewCudaResource));
        checkCudaErrors(cudaStreamSynchronize(0));

        glBindTexture(GL_TEXTURE_2D, viewGLTexture);
        {
            glBegin(GL_QUADS);
            {
                 glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f, -1.0f);
                 glTexCoord2f(1.0f, 0.0f); glVertex2f(+1.0f, -1.0f);
                 glTexCoord2f(1.0f, 1.0f); glVertex2f(+1.0f, +1.0f);
                 glTexCoord2f(0.0f, 1.0f); glVertex2f(-1.0f, +1.0f);
            }
            glEnd();
         }
         glBindTexture(GL_TEXTURE_2D, 0);
         glFinish();
    }

    int main(int argc, char **argv)
    {
         initGLandCUDA();

        glutDisplayFunc(renderFrame);
        //glutKeyboardFunc(keyboard);
        //glutMouseFunc(mouse);
        glutMainLoop();
    }

这似乎是某种超出范围的错误,但我目前没有想法(顺便说一句,这是 cc 3.0,运行到 nVidia 650M)。

编辑: 我所说的崩溃是指:崩溃。电脑死机。我无法移动鼠标,必须重新启动。

是的,我已经查看了所有示例,它们并不完全是我想要的。将它们更改为我想要的结果会导致此问题。如果手册或其他任何地方有任何其他帮助可以帮助我,而且我发现我不会费心寻求帮助。您需要链接 cuda_runtime 和 glut 库

最佳答案

下面是您的代码的工作版本。您的代码中的问题是:

  • 您的内核依赖于使用 512x512 线程启动,但您仅使用 64x1 线程启动。

  • 您的内核正在使用 surf2Dwrite() 写入未对齐的地址。

  • 您在 OpenGL 中设置了双缓冲,但没有交换缓冲区。 (glutSwapBuffers())。

  • 您正在使用 float 初始化 uchar4

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>

#ifdef _WIN32
#  define WINDOWS_LEAN_AND_MEAN
#  define NOMINMAX
#  include <windows.h>
#endif

// OpenGL Graphics includes
#include <GL/glew.h>
#if defined (__APPLE__) || defined(MACOSX)
#include <GLUT/glut.h>
#else
#include <GL/freeglut.h>
#endif

#include <cuda_runtime.h>
#include <cuda_gl_interop.h>

#include <vector_types.h>
const unsigned int window_width  = 512;
const unsigned int window_height = 512;

GLuint viewGLTexture;
cudaGraphicsResource_t viewCudaResource;

#define check(ans) { _check((ans), __FILE__, __LINE__); }
inline void _check(cudaError_t code, char *file, int line)
{
  if (code != cudaSuccess) {
    fprintf(stderr,"CUDA Error: %s %s %d\n", cudaGetErrorString(code), file, line);
    exit(code);
  }
}

void initGLandCUDA() {
  int argc = 0;
  char** argv = NULL;
  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_RGBA);
  glutInitWindowSize(window_width, window_height);
  glutCreateWindow("CUDA GL Interop");

  glewInit();

  glEnable(GL_TEXTURE_2D);
  glGenTextures(1, &viewGLTexture);
  glBindTexture(GL_TEXTURE_2D, viewGLTexture);

  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, window_width, window_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
  glBindTexture(GL_TEXTURE_2D, 0);

  check(cudaGLSetGLDevice(0));

  check(cudaGraphicsGLRegisterImage(&viewCudaResource, viewGLTexture, GL_TEXTURE_2D, cudaGraphicsRegisterFlagsWriteDiscard));
}    


__global__ void renderingKernel(cudaSurfaceObject_t image) {
  unsigned int x = blockIdx.x * blockDim.x + threadIdx.x;
  unsigned int y = blockIdx.y * blockDim.y + threadIdx.y;

  uchar4 color = make_uchar4(x / 2, y / 2, 0, 127);
  surf2Dwrite(color, image, x * sizeof(color), y, cudaBoundaryModeClamp);
}


void callCUDAKernel(cudaSurfaceObject_t image) {
  dim3 block(256, 1, 1);
  dim3 grid(2, 512, 1);
  renderingKernel<<<grid, block>>>(image);
  check(cudaPeekAtLastError());
  check(cudaDeviceSynchronize());
}

void renderFrame() {
  check(cudaGraphicsMapResources(1, &viewCudaResource));

  cudaArray_t viewCudaArray;
  check(cudaGraphicsSubResourceGetMappedArray(&viewCudaArray, viewCudaResource, 0, 0));

  cudaResourceDesc viewCudaArrayResourceDesc;
  memset(&viewCudaArrayResourceDesc, 0, sizeof(viewCudaArrayResourceDesc));
  viewCudaArrayResourceDesc.resType = cudaResourceTypeArray;
  viewCudaArrayResourceDesc.res.array.array = viewCudaArray;

  cudaSurfaceObject_t viewCudaSurfaceObject;
  check(cudaCreateSurfaceObject(&viewCudaSurfaceObject, &viewCudaArrayResourceDesc));

  callCUDAKernel(viewCudaSurfaceObject);

  check(cudaDestroySurfaceObject(viewCudaSurfaceObject));

  check(cudaGraphicsUnmapResources(1, &viewCudaResource));

  check(cudaStreamSynchronize(0));

  glBindTexture(GL_TEXTURE_2D, viewGLTexture);
  {
    glBegin(GL_QUADS);
    {
      glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f, -1.0f);
      glTexCoord2f(1.0f, 0.0f); glVertex2f(+1.0f, -1.0f);
      glTexCoord2f(1.0f, 1.0f); glVertex2f(+1.0f, +1.0f);
      glTexCoord2f(0.0f, 1.0f); glVertex2f(-1.0f, +1.0f);
    }
    glEnd();
  }
  glBindTexture(GL_TEXTURE_2D, 0);
  glFinish();
}

int main(int argc, char **argv)
{
  initGLandCUDA();

  glutDisplayFunc(renderFrame);
  //glutKeyboardFunc(keyboard);
  //glutMouseFunc(mouse);
  glutMainLoop();
}

输出:

enter image description here

关于c++ - CUDA/OGL 互操作崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20762828/

相关文章:

c++ - 如何在启用 ANSI 的同时在 gcc 中启用 C++ 样式的注释?

c++ - OpenCL clEnqueueTasks 并行性

cuda - CUDA 中的原子 Saxpy

Java 线程或 Cuda 线程

c++ - 如何在 std::vector 中找到 std::pair 的第二个元素的最大值?

c++ - 如何为 Debug模式优化大循环

c++ - 无论我使用什么输入/窗口处理程序,OpenGL 代码都可以工作吗?

opengl - Z轴什么时候翻转? (OpenGL)

opengl - GLSL 中到相机平面的距离为深度

visual-studio-2010 - 使用 CUDA 和 Armadillo