From 3e8847801f1bb15f0c3b07f00827f4447be067a7 Mon Sep 17 00:00:00 2001 From: Sylvain Munaut Date: Fri, 25 Aug 2023 09:02:18 +0200 Subject: [PATCH] linux/clgl: Add support for sharing GL buffer Signed-off-by: Sylvain Munaut --- .../sharings/gl/linux/gl_buffer_linux.cpp | 103 +++++++++++++----- 1 file changed, 75 insertions(+), 28 deletions(-) diff --git a/opencl/source/sharings/gl/linux/gl_buffer_linux.cpp b/opencl/source/sharings/gl/linux/gl_buffer_linux.cpp index 52d42494cdd37..6dee01c5b476b 100644 --- a/opencl/source/sharings/gl/linux/gl_buffer_linux.cpp +++ b/opencl/source/sharings/gl/linux/gl_buffer_linux.cpp @@ -24,16 +24,65 @@ using namespace NEO; Buffer *GlBuffer::createSharedGlBuffer(Context *context, cl_mem_flags flags, unsigned int bufferId, cl_int *errcodeRet) { ErrorCodeHelper errorCode(errcodeRet, CL_SUCCESS); -#if 0 - CL_GL_BUFFER_INFO bufferInfo = {0}; - bufferInfo.bufferName = bufferId; + /* Prepare export request */ + struct mesa_glinterop_export_in objIn = {}; + struct mesa_glinterop_export_out objOut = {}; + + objIn.version = MESA_GLINTEROP_EXPORT_IN_VERSION; + objIn.target = GL_ARRAY_BUFFER; + objIn.obj = bufferId; + + switch (flags) { + case CL_MEM_READ_ONLY: + objIn.access = MESA_GLINTEROP_ACCESS_READ_ONLY; + break; + case CL_MEM_WRITE_ONLY: + objIn.access = MESA_GLINTEROP_ACCESS_WRITE_ONLY; + break; + case CL_MEM_READ_WRITE: + objIn.access = MESA_GLINTEROP_ACCESS_READ_WRITE; + break; + default: + errorCode.set(CL_INVALID_VALUE); + return nullptr; + } + + objOut.version = MESA_GLINTEROP_EXPORT_OUT_VERSION; + + /* Call MESA interop */ GLSharingFunctionsLinux *sharingFunctions = context->getSharing(); - if (sharingFunctions->acquireSharedBufferINTEL(&bufferInfo) == GL_FALSE) { - errorCode.set(CL_INVALID_GL_OBJECT); + + int retValue = sharingFunctions->exportObject(&objIn, &objOut); + if ((retValue != MESA_GLINTEROP_SUCCESS) || (objOut.version != MESA_GLINTEROP_EXPORT_OUT_VERSION)) { + switch (retValue) { + case MESA_GLINTEROP_INVALID_DISPLAY: + case MESA_GLINTEROP_INVALID_CONTEXT: + errorCode.set(CL_INVALID_CONTEXT); + break; + case MESA_GLINTEROP_INVALID_OBJECT: + errorCode.set(CL_INVALID_GL_OBJECT); + break; + case MESA_GLINTEROP_OUT_OF_HOST_MEMORY: + errorCode.set(CL_OUT_OF_HOST_MEMORY); + break; + case MESA_GLINTEROP_OUT_OF_RESOURCES: + default: + errorCode.set(CL_OUT_OF_RESOURCES); + break; + } + return nullptr; } + /* Map result for rest of the function */ + CL_GL_BUFFER_INFO bufferInfo = { + .bufferName = bufferId, + .globalShareHandle = static_cast(objOut.dmabuf_fd), + .bufferSize = static_cast(objOut.buf_size), + .bufferOffset = static_cast(objOut.buf_offset), + }; + auto graphicsAllocation = GlBuffer::createGraphicsAllocation(context, bufferId, bufferInfo); if (!graphicsAllocation) { errorCode.set(CL_INVALID_GL_OBJECT); @@ -46,30 +95,26 @@ Buffer *GlBuffer::createSharedGlBuffer(Context *context, cl_mem_flags flags, uns multiGraphicsAllocation.addAllocation(graphicsAllocation); return Buffer::createSharedBuffer(context, flags, glHandler, std::move(multiGraphicsAllocation)); -#endif - errorCode.set(CL_INVALID_GL_OBJECT); - return nullptr; } void GlBuffer::synchronizeObject(UpdateData &updateData) { -#if 0 auto sharingFunctions = static_cast(this->sharingFunctions); - CL_GL_BUFFER_INFO bufferInfo = {}; - bufferInfo.bufferName = this->clGlObjectId; - sharingFunctions->acquireSharedBufferINTEL(&bufferInfo); + /* Prepare flush request */ + struct mesa_glinterop_export_in objIn = {}; - auto graphicsAllocation = updateData.memObject->getGraphicsAllocation(updateData.rootDeviceIndex); + objIn.version = MESA_GLINTEROP_EXPORT_IN_VERSION; + objIn.target = GL_ARRAY_BUFFER; + objIn.obj = this->clGlObjectId; - updateData.sharedHandle = bufferInfo.globalShareHandle; - updateData.synchronizationStatus = SynchronizeStatus::ACQUIRE_SUCCESFUL; - graphicsAllocation->setAllocationOffset(bufferInfo.bufferOffset); - - const auto currentSharedHandle = graphicsAllocation->peekSharedHandle(); - if (currentSharedHandle != updateData.sharedHandle) { - updateData.updateData = new CL_GL_BUFFER_INFO(bufferInfo); + /* Call MESA interop */ + int retValue = sharingFunctions->flushObjects(1, &objIn, nullptr); + if (retValue != MESA_GLINTEROP_SUCCESS) { + updateData.synchronizationStatus = SynchronizeStatus::SYNCHRONIZE_ERROR; + return; } -#endif + + updateData.synchronizationStatus = SynchronizeStatus::ACQUIRE_SUCCESFUL; } void GlBuffer::resolveGraphicsAllocationChange(osHandle currentSharedHandle, UpdateData *updateData) { @@ -159,7 +204,7 @@ GraphicsAllocation *GlBuffer::createGraphicsAllocation(Context *context, unsigne context->getDeviceBitfieldForAllocation(context->getDevice(0)->getRootDeviceIndex())}; // couldn't find allocation for reuse - create new graphicsAllocation = - context->getMemoryManager()->createGraphicsAllocationFromSharedHandle(bufferInfo.globalShareHandle, properties, true, false, false, nullptr); + context->getMemoryManager()->createGraphicsAllocationFromSharedHandle(bufferInfo.globalShareHandle, properties, false, false, false, nullptr); } if (!graphicsAllocation) { @@ -173,6 +218,12 @@ GraphicsAllocation *GlBuffer::createGraphicsAllocation(Context *context, unsigne DEBUG_BREAK_IF(graphicsAllocation->getDefaultGmm() != nullptr); auto helper = context->getDevice(0)->getRootDeviceEnvironment().getGmmHelper(); graphicsAllocation->setDefaultGmm(new Gmm(helper, bufferInfo.pGmmResInfo)); + } else { + auto helper = context->getDevice(0)->getRootDeviceEnvironment().getGmmHelper(); + StorageInfo storageInfo = {}; + + graphicsAllocation->setDefaultGmm(new Gmm(helper, + nullptr, bufferInfo.bufferSize, 1, GMM_RESOURCE_USAGE_UNKNOWN, false, storageInfo, false)); } } @@ -180,10 +231,6 @@ GraphicsAllocation *GlBuffer::createGraphicsAllocation(Context *context, unsigne } void GlBuffer::releaseResource(MemObj *memObject, uint32_t rootDeviceIndex) { -#if 0 - auto sharingFunctions = static_cast(this->sharingFunctions); - CL_GL_BUFFER_INFO bufferInfo = {}; - bufferInfo.bufferName = this->clGlObjectId; - sharingFunctions->releaseSharedBufferINTEL(&bufferInfo); -#endif + auto memoryManager = memObject->getMemoryManager(); + memoryManager->closeSharedHandle(memObject->getGraphicsAllocation(rootDeviceIndex)); }