Question

I would just like to start by saying I am new to CUDA and OpenGL. I get the above runtime error when it runs glutMainLoop() and the mainloop runs glDrawPixels(). I have looked everywhere to figure out why this isn't working any help would be appreciated.

#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);
}
Était-ce utile?

La solution

Unless you are using a Pixel Buffer Object, then this is exactly the sort of behavior you should expect from glDrawPixels (..., 0). That last parameter is a pointer to pixel data, it should be non-NULL whenever the source of pixel data is client memory. It can be NULL if you have a Pixel Buffer Object, the same way that the pointer in a call to glVertexPointer (...) can be NULL when using a Vertex Buffer Object.

You have acquired the necessary function pointers to create a Pixel Buffer Object in your code, however have not actually created one. Thus, passing NULL to glDrawPixels (...) will cause the driver to dereference a NULL pointer.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top