如何在 OpenCL 内核中更新 OpenCL-OpenGL 共享缓冲区数据?

Posted

技术标签:

【中文标题】如何在 OpenCL 内核中更新 OpenCL-OpenGL 共享缓冲区数据?【英文标题】:How to update OpenCL-OpenGL shared buffer data in OpenCL kernel? 【发布时间】:2016-02-23 10:16:13 【问题描述】:

我正在尝试从 OpenCL 内核填充 OpenCL-OpenGL 共享缓冲区。我编写了一个简单的程序来绘制 3 个点。 3 个顶点的 (x,y,z) 值填充到内核中。但是这些点没有按预期绘制。我知道我没有正确访问共享缓冲区。代码如下:

cl_GLuint vbo;
struct vertex

  float x, y, z, w; // position

pos[3];


void CreateVBO()

   glGenBuffers(1,&vbo);
   glBindBuffer(GL_ARRAY_BUFFER,vbo);
   glBufferData(GL_ARRAY_BUFFER,3*sizeof(vertex),pos,GL_DYNAMIC_DRAW);



void Display(void)


    glLoadIdentity();
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glPointSize(10.0);
    CreateVBO();
    glBindBuffer(GL_ARRAY_BUFFER,vbo);
    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(4, GL_FLOAT, 0, 0);
    glDrawArrays(GL_POINTS,0,3);
    glDisableClientState(GL_VERTEX_ARRAY);
    glBindBuffer(GL_ARRAY_BUFFER,0);  
    glutSwapBuffers();


void InitGL(int argc , char * argv[])

    glutInit(&argc , argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
    glutCreateWindow("Draw Points");
    glewInit();   
    glutDisplayFunc(Display);
    glClearColor(0,0,0,1);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glMatrixMode(GL_MODELVIEW);
    glEnable( GL_POINT_SMOOTH | GL_DEPTH_TEST );


//MAIN program  

global_item_size = local_item_size = 1
InitGL(argc,argv);

//set properties
cl_context_properties properties[] =

    CL_GL_CONTEXT_KHR,   (cl_context_properties)wglGetCurrentContext(),
    CL_WGL_HDC_KHR,      (cl_context_properties)wglGetCurrentDC(),
    CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i], 
    0
;

/* Create OpenCL context */
context = clCreateContext(properties, 1, device_id, NULL, NULL, &ret);

/* Create Command Queue */
cmd_queue = clCreateCommandQueue(context, device_id[0], 0, &ret);

/* Create Kernel Program from the source */
program = clCreateProgramWithSource(context, 1, (const char **)&source_str, (const size_t *)&source_size, &ret);

/* Build Kernel Program */
ret = clBuildProgram(program, 1, device_id, NULL, NULL, NULL);

/* Create OpenCL Kernel */ 
kernel = clCreateKernel(program, "drawPoints", &ret);

/* create opencl buffer*/
vbo_cl = clCreateFromGLBuffer(context,CL_MEM_READ_WRITE,vbo,NULL);

/* Set OpenCL Kernel Parameters */
ret = clSetKernelArg(kernel, 0,sizeof(cl_mem), (void *)&vbo_cl); //,

glFlush(); 
ret = clEnqueueAcquireGLObjects(cmd_queue, 1, &vbo_cl, 0,0,0);

/* Execute OpenCL Kernel */
ret = clEnqueueNDRangeKernel(cmd_queue, kernel, 1, NULL,&global_item_size, &local_item_size, 0, NULL, &event);

ret = clEnqueueReleaseGLObjects(cmd_queue, 1, &vbo_cl, 0,0,0);
clFinish(cmd_queue);

Display();
glutMainLoop();




//KERNEL CODE (Nvidia 820M Geforce GPU )
__kernel void drawPoints(__global float4* buffer) 

buffer[0] = (float4)(0, 1, -1, 1.0f);
buffer[1] = (float4)(-1, -1, -1, 1.0f);
buffer[2] = (float4)(1, -1, -1, 1.0f);

我使用的是 NVIDIA Geforce 820M GPU。目前内核只填充缓冲区。我尝试在CreateVBO() 函数中初始化pos[3] 值,然后尝试在内核中更新它。在这两种情况下,程序都执行没有任何错误。在坐标 (0,0,0) 处绘制了一个点,这不是预期的结果。请让我知道从 OpenCL 内核修改/更新 OpenGL 缓冲区数据的正确方法。

【问题讨论】:

【参考方案1】:

好的。我发现了问题。我在DisplayGL() 内打电话给CreateVBO();CreateVBO() 初始化缓冲区并因此设置为 (0,0,0)。

【讨论】:

以上是关于如何在 OpenCL 内核中更新 OpenCL-OpenGL 共享缓冲区数据?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 OpenCL 中使用本地内存?

如何使用 PyOpenCL 将带有数组和变量的 C 结构传递给 OpenCL 内核

从 OpenCL 内核修改 VBO 数据

如何强制 OpenCL 不重新对齐结构?

如何正确初始化此 C++ for openCL 内核的输入/输出参数?

OpenCL 内核在 Nvidia GPU 上每个线程使用多少寄存器?