Skip to content

Commit

Permalink
linux/clgl: Add support for sharing GL buffer
Browse files Browse the repository at this point in the history
Signed-off-by: Sylvain Munaut <[email protected]>
  • Loading branch information
smunaut committed Oct 9, 2023
1 parent 04e817b commit 3e88478
Showing 1 changed file with 75 additions and 28 deletions.
103 changes: 75 additions & 28 deletions opencl/source/sharings/gl/linux/gl_buffer_linux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<GLSharingFunctionsLinux>();
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<unsigned int>(objOut.dmabuf_fd),
.bufferSize = static_cast<GLint>(objOut.buf_size),
.bufferOffset = static_cast<GLint>(objOut.buf_offset),
};

auto graphicsAllocation = GlBuffer::createGraphicsAllocation(context, bufferId, bufferInfo);
if (!graphicsAllocation) {
errorCode.set(CL_INVALID_GL_OBJECT);
Expand All @@ -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<GLSharingFunctionsLinux *>(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) {
Expand Down Expand Up @@ -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) {
Expand All @@ -173,17 +218,19 @@ 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));
}
}

return graphicsAllocation;
}

void GlBuffer::releaseResource(MemObj *memObject, uint32_t rootDeviceIndex) {
#if 0
auto sharingFunctions = static_cast<GLSharingFunctionsLinux *>(this->sharingFunctions);
CL_GL_BUFFER_INFO bufferInfo = {};
bufferInfo.bufferName = this->clGlObjectId;
sharingFunctions->releaseSharedBufferINTEL(&bufferInfo);
#endif
auto memoryManager = memObject->getMemoryManager();
memoryManager->closeSharedHandle(memObject->getGraphicsAllocation(rootDeviceIndex));
}

0 comments on commit 3e88478

Please sign in to comment.