Tool/software: Linux
I'm using tda2px platform with vision sdk: software-dl.ti.com/processor-sdk-vision/esd/TDAx/vision-sdk/latest/index_FDS.html
Currently trying to setup a background processing pipeline sharing the workload between GPU and CPU. The GPU needs to render some offscreen data, which the CPU can process further.
In order to do this I require a userspace mapped buffer to be passed as an OpenGL resource.
Usually on the GPU side this is achieved by GL/EGL: EGLImage -> eglImageTargetRenderbufferStorage -> glFramebufferRenderbuffer -> glDraw*
I found utilities in vision_sdk/links_fw/src/hlos/system/system_egl_context.h being used in the ADAS demos for mapping the camera frame as a GPU resource.
System_EglWindowObj* pEglObj; EGLCompatBuffer eglCBuf = pEglObj->eglInfo.get_egl_attach_buffer(buf_width, buf_height, SYSTEM_DF_RGB24_888 /*buf_format*/, buf_memory_pointer); EGLImageKHR img = eglCreateImageKHR(pEglObj->display, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, (EGLNativePixmapType)(eglCBuf.eglPixmap), NULL);
So now the question is how to get a contiguous memory region shared between the GPU/CPU and map it to our process.
I have gotten this far:
Use Generic Buffer Manager: ti_components/os_tools/linux/targetfs/usr/include/gbm/gbm.h to create the shared buffer
Use Direct Rendering Manager: ti_components/os_tools/linux/targetfs/usr/include/xf86drm.h to map the buffer to process userspace
Here is some pseudocode with error checking omitted:
struct gbm_device* gbmDev = (gbm_device*)pEglObj->nativeDisplay; int fd = drmOpen("omapdrm", NULL); // drm handle struct gbm_bo* bo = gbm_bo_create(gbmDev, buf_width, buf_height, GBM_BO_FORMAT_ARGB8888 /*buf_format*/, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); int bo_fd = gbm_bo_get_fd(bo); union gbm_bo_handle bo_handle = gbm_bo_get_handle(bo); struct drm_mode_map_dumb mreq = {0}; mreq.handle = bo_handle.ptr; int ret = drmIoctl(fd /*bo_fd?*/, DRM_IOCTL_MODE_MAP_DUMB, &mreq); void* map = mmap(0, buf_width*buf_height*4 /*creq.size*/, PROT_READ | PROT_WRITE, MAP_SHARED, bo_fd, mreq.offset);
The GBM buffer object seems to be properly created, having a handle and file descriptor, but I cannot get it mapped:
drmIoctl - returns -1, so we can't map the buffer object in order to provide the pointer to get_egl_attach_buffer.
Is this the right approach to this particular problem or is there a better way of achieving this functionality?
A follow up question will be about cache control, what tools are provided to invalidate/flush the shared buffer when switching processing from CPU to GPU and vice versa?
Thank you in advance,
Best Regards,
Yavor