Используя OpenGL и Cuda, вы получаете ошибку времени выполнения для места чтения нарушения доступа

Я просто хотел бы начать с того, что я новичок в CUDA и OpenGL. Я получаю вышеуказанную ошибку во время выполнения при запуске glutMainLoop() и основной цикл работает glDrawPixels(), Я искал везде, чтобы понять, почему это не работает, любая помощь будет оценена.

#include<stdio.h>
#include<stdlib.h>
#include<gl/glut.h>
#include<stb_image.c>
#include<cuda.h>
#include<cuda_gl_interop.h>
#include<gl/glext.h>

static void HandleError( cudaError_t err, const char *file, int line ) {
    if (err != cudaSuccess) {
        fprintf(stderr, "%s in %s at line %d\n", cudaGetErrorString( err ), file, line );
        system("PAUSE");
        //exit( EXIT_FAILURE );
    }
}
#define HANDLE_ERROR( err ) (HandleError( err, __FILE__, __LINE__ ))
#define DIM  512
#define GET_PROC_ADDRESS( str ) wglGetProcAddress( str )
PFNGLBINDBUFFERARBPROC    glBindBuffer     = NULL;
PFNGLDELETEBUFFERSARBPROC glDeleteBuffers  = NULL;
PFNGLGENBUFFERSARBPROC    glGenBuffers     = NULL;
PFNGLBUFFERDATAARBPROC    glBufferData     = NULL;

GLuint  bufferObj;          /* how OpenGL calls the buffer */
cudaGraphicsResource *resource;     /* how CUDA calls this same buffer */

uchar4* devPtr;             /* friendly pointer to the handles above */

const int size = DIM * DIM;
struct cuComplex
{
    float r;
    float i;

    __device__ cuComplex(float a, float b) : r(a), i(b){    }
    __device__ float magnitude2(void)
    {
        return r * r + i * i;
    }
    __device__ cuComplex operator *(const cuComplex & a)
    {
        return cuComplex(r*a.r - i*a.i, i*a.r + r*a.i);
    }
    __device__ cuComplex operator+(const cuComplex & a)
    {
        return cuComplex(r+a.r, i+a.i);
    }
};

__device__ int julia (int x, int y)
{
    const float scale = 1.5;
    float jx = scale *(float)(DIM/2 - x)/(DIM/2);
    float jy = scale *(float)(DIM/2 - y)/(DIM/2);

    cuComplex c(-0.8, 0.156);
    cuComplex a(jx,jy);

    int i = 0;
    for(i=0; i<200; i++)
    {
        a = a * a + c;
        if(a.magnitude2() > 1000)
        {
            return 0;
        }
    }
    return 1;
}

__global__ void kernel(uchar4 *ptr)
{
    int x = blockIdx.x;
    int y = blockIdx.y;
    int offset = x + y * gridDim.x * blockDim.x;

    int juliaValue = julia(x,y);
    ptr[offset].x = 255 * juliaValue;
    ptr[offset].y = 0;
    ptr[offset].z = 0;
    ptr[offset].w = 255;

}


static void Draw( void ) {
    glDrawPixels( DIM, DIM, GL_RGBA, GL_UNSIGNED_BYTE,0); //ERROR HAPPENS HERE
    glutSwapBuffers();
}

void display_and_exit() {
    cudaDeviceProp  prop;
    int dev;

    memset( &prop, 0, sizeof( cudaDeviceProp ) );
    prop.major = 1;
    prop.minor = 0;
    HANDLE_ERROR( cudaChooseDevice( &dev, &prop ) );

    /*
     * Interoperability with OpenGL requires that the CUDA device 
     * be specified by cudaGLSetGLDevice() before any other runtime calls.
     */
    HANDLE_ERROR( cudaGLSetGLDevice( dev ) );




    /* 
     * a bug in the Windows GLUT implementation prevents us from
     * passing zero arguments to glutInit()
     */
    int c=1;
    char* dummy = "";
    glutInit( &c, &dummy );
    glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGBA );
    glutInitWindowSize (DIM, DIM);
    glutInitWindowPosition (100, 100);
    glutCreateWindow("CUDA and OpenGL example" );
    printf("OpenGL version: %s\n", glGetString(GL_VERSION));
    dim3 grid(DIM, DIM);
    kernel<<<grid,1>>>(devPtr);
    glutDisplayFunc(Draw);

    /*
     * Get pointers to functions (glext.h)
     */
    glBindBuffer    = (PFNGLBINDBUFFERARBPROC)GET_PROC_ADDRESS("glBindBuffer");
    glDeleteBuffers = (PFNGLDELETEBUFFERSARBPROC)GET_PROC_ADDRESS("glDeleteBuffers");
    glGenBuffers    = (PFNGLGENBUFFERSARBPROC)GET_PROC_ADDRESS("glGenBuffers");
    glBufferData    = (PFNGLBUFFERDATAARBPROC)GET_PROC_ADDRESS("glBufferData");

    glutMainLoop(); 
}

int main() {
    display_and_exit();
    return(0);
}

1 ответ

Решение

Если вы не используете объект Pixel Buffer, то это именно то поведение, которое вы должны ожидать от glDrawPixels (..., 0), Этот последний параметр является указателем на данные пикселей, он должен быть ненулевым, если источником данных пикселей является память клиента. Это может быть NULL, если у вас есть объект Pixel Buffer, так же, как указатель в вызове glVertexPointer (...) может быть NULL при использовании объекта буфера вершин.

Вы приобрели необходимые функциональные указатели для создания объекта Pixel Buffer в своем коде, но на самом деле не создали его. Таким образом, передав NULL glDrawPixels (...) заставит драйвер разыменовать нулевой указатель.

Другие вопросы по тегам