視頻處理如果能使用OpenCL、OpenGL、omap將大量提高運算速度,簡單介紹OpenCL、OpenGL 同時工作。
OpenCL和OpenGL都能用於操作GPU,但是前者主要用於通用計算,而後者主要用於映像渲染。在某些情況下,我們希望能用OpenCL計得到算映像,然後展示在顯示器上。如果直接調用OpenGL的現有API,則需要把計算得到的結果通過pci-e匯流排傳回host端記憶體,再由OpenGL再次通過pci-e匯流排傳回gpu端顯存。這樣就造成了額外的拷貝,傳輸開銷。事實上,可以使用OpenCL的OpenGL擴充功能,使得OpenCL和OpenGL能共用buffer,從而避免額外的傳輸。這種共用可以通俗的理解為是讓OpenCL和OpenGL共用同一塊記憶體的指標。
要實現這種共用需要三步:
1.OpenCL在OpenGL的上下文基礎上建立上下文
//建立內容相關的屬性
cl_context_properties properties[] = {
CL_GL_CONTEXT_KHR, (cl_context_properties) wglGetCurrentContext(), //獲得OpenGL上下文
CL_WGL_HDC_KHR, (cl_context_properties) wglGetCurrentDC(), //獲得OpenGl裝置資訊
CL_CONTEXT_PLATFORM, (cl_context_properties) platform, //獲得平台資訊
0};
//利用剛剛建立的屬性建立上下文
ctx = clCreateContext(properties, 1, &device, NULL, NULL, &err);
2.OpenCL在OpenGL記憶體對象的基礎上建立記憶體對象
//以buffer為例,需要一個OpenGL的vbo才能建立共用的記憶體對象
cl_mem clCreateFromGLBuffer(cl_context context, cl_mem_flags flags,
GLuint vbo_desc, cl_int *err)
注意:OpenGL的記憶體對象必須先行建立,使用OpenCL中的image則需要OpenGL中的texture
3.共用記憶體對象的同步及訪問
很顯然OpenCL和OpenGL不能同時去訪問同一個資料對象,需要加鎖,解鎖進行同步
//加鎖
int clEnqueueAcquireGLObjects(cl_command_queue queue, cl_uint num_objects,
const cl_mem *mem_objects, cl_uint num_events_in_wait_list,
const cl_event *event_wait_list, cl_event *event)
//加鎖後在該處運行openCL代碼
//解鎖
int clEnqueueReleaseGLObjects(cl_command_queue queue, cl_uint num_objects,
const cl_mem *mem_objects, cl_uint num_events_in_wait_list,
const cl_event *event_wait_list, cl_event *event)
做完這三步後,OpenGL即可直接使用共用的記憶體對象進行渲染及其他動作。
更加詳細的資訊請參考:Understanding OpenCL-OpenGL Interoperability
OpenCL / OpenGL Interoperation 教程及執行個體