Reputation: 828
It is a CUDA Code which performs ray tracing. The OpenGL window is used to display the output of the ray tracing performed. Since, the RayTrace is quite slow, I am not particularly concerned about OpenGL performace etc.
But when the ray-tracing (startRayTrace()) is called, the OpenGL window just goes to "Not Responding" State, and displays the output once the ray tracing is finished.
I can't figure out how to prevent it going into the not-respond state. When it goes in not respond state, I cannot minimize the window etc. but the rendered image is still shown as it is.
void display(void) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glLoadIdentity();
float image[768][1024][3] = { 0 };
for (int i = 0; i < 768; ++i) {
for (int j = 0; j < 1024; ++j) {
int idx = (767 - i) * 1024 + j;
image[i][j][0] = host_c[idx].x;
image[i][j][1] = host_c[idx].y;
image[i][j][2] = host_c[idx].z;
}
}
glRasterPos2i(-1, -1);
glDrawPixels(1024, 768, GL_RGB, GL_FLOAT, image);
glEnd();
glutSwapBuffers();
}
void winResize(int w, int h) {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport( (w>1024)?((w-1024)/2):(0), (h>768)?((h-768)/2):(0), w, h);
glMatrixMode(GL_MODELVIEW);
}
void startRayTrace() {
cudaMemcpyToSymbol(cam_offset, &cam_offset_global, sizeof(double), 0, cudaMemcpyHostToDevice);
init <<< 1, 1 >>> ();
cudaDeviceSynchronize();
char title[35];
//rayTrace <<<48, 16 >>> ();
//cudaDeviceSynchronize();
for (int i = 0; i < 24; ++i) {
rayTrace <<< 1, 32 >>> (); //Overcome Watchdog timer on Windows without disabling TDR
cudaDeviceSynchronize();
sprintf(title, "Ray Tracing | Rendering %.2f%%...", ((i + 1) / 24.f) * 100);
glutSetWindowTitle(title);
}
copyToHost <<< 1, 1 >>> (dev_c);
cudaMemcpy(host_c, dev_c, WIDTH * HEIGHT * sizeof(vector), cudaMemcpyDeviceToHost);
}
void keyPress(unsigned char key, int x, int y) {
if (key == 'd') {
cam_offset_global += 10;
}
if (key == 'a') {
cam_offset_global -= 10;
}
}
void keyUp(unsigned char key, int x, int y) {
if (key == 'd' || key == 'a') {
startRayTrace();
}
//cudaDeviceSynchronize();
glutPostRedisplay();
}
int main(int argc, char * argv[]) {
cudaMalloc(&dev_c, WIDTH * HEIGHT * sizeof(vector));
//OpenGL Window
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB);
glutInitWindowPosition(100, 100);
glutInitWindowSize(1024, 768);
glutCreateWindow("Ray Tracing | Rendering 0%...");
//Ray Tracing
startRayTrace();
cudaDeviceSynchronize();
const GLubyte* ren = glGetString(GL_RENDERER);
printf("\n\n\n OpenGL Renderer : %s \n\n", ren);
//Register Callbacks
glutDisplayFunc(display);
glutReshapeFunc(winResize);
glutKeyboardFunc(keyPress);
glutKeyboardUpFunc(keyUp);
glutMainLoop();
delete[] host_c;
cudaFree(dev_c);
return 0;
}
Once the ray-trace is done, the host_c[] stores the image data, which I use to display the output on glWindow. The glutPostRedisplay() is supposed to re-render the output once ray trace finishes and host_c[] is updated, but the glWindow hangs until the ray-tracing finishes.
Upvotes: 0
Views: 777
Reputation: 162367
GLUT is not going to read further events, while it's being right inside an event hand.er You're calling startRayTrace
right from the keyboard callback. However startRayTrace
doesn't just start the raytrace, it also waits for completion. And because of that, GLUT will be stuck until the raytrace finishes.
CUDA kernels are executed asynchronously. To get note of when the kernel finishes, add a cudaEvent
right after the kernel in the CUDA stream. Then register a GLUT idle
callback function. In that function, poll if the event did complete, and when the event did complete, issue a glutPostRedisplay
.
Do not cudaSync…
inside the keyboard function, because that will stall.
Upvotes: 2