gpt4 book ai didi

c++ - 在 GPU 上执行计算时 OpenGL 窗口没有响应

转载 作者:行者123 更新时间:2023-11-28 01:27:13 24 4
gpt4 key购买 nike

这是一个执行光线追踪的 CUDA 代码。 OpenGL 窗口用于显示执行的光线追踪的输出。由于 RayTrace 非常慢,我并不是特别关心 OpenGL 性能等。

但是当调用光线追踪 (startRayTrace()) 时,OpenGL 窗口会进入“无响应”状态,并在光线追踪完成后显示输出。

我不知道如何防止它进入无响应状态。当它进入无响应状态时,我无法最小化窗口等。但渲染图像仍按原样显示。

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;
}

光线追踪完成后,host_c[] 会存储图像数据,我使用这些数据在 glWindow 上显示输出。 glutPostRedisplay() 应该在光线追踪完成并且 host_c[] 更新后重新渲染输出,但是 glWindow 挂起直到光线追踪完成。

最佳答案

GLUT 不会读取更多事件,而它就在事件处理程序中。呃,您正在从键盘回调中调用 startRayTrace。然而 startRayTrace 不只是开始光线追踪,它还在等待完成。因此,GLUT 将被卡住,直到光线追踪完成。

CUDA 内核是异步执行的。要记下内核何时完成,请在 CUDA 流中的内核之后添加一个 cudaEvent。然后注册一个GLUT idle回调函数。在该函数中,轮询事件是否完成,当事件完成时,发出 glutPostRedisplay

不要cudaSync…在键盘函数中,因为那样会停止。

关于c++ - 在 GPU 上执行计算时 OpenGL 窗口没有响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53208958/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com