mirror of
https://github.com/intel/compute-runtime.git
synced 2025-12-19 06:24:51 +08:00
This commit is aimed at drastically improving the support for the CL/GL sharing extension on linux. The current support is not really usable as it only supports a few texture format, and only on EGL contexts. It is also pretty buggy since it requires the texture to be bound when placing the CL call to share it which is just plain wrong and will not work in many applications. This new version makes used of the "official" interop extension from MESA which is available for GLX and EGL contexts, allows sharing of buffers and not just texture and supports many more formats. This is still far from being a fully compliant / full featured version of the extension, but it's a big step forward in my opinion and allows to run some real applications. I've tested gr-fosphor (SDR spectrum display) and Davinci Resolve as examples. Both of theses don't work without theses improvements. Fixes: https://github.com/intel/compute-runtime/issues/659 Fixes: https://github.com/intel/compute-runtime/issues/667 https://github.com/intel/compute-runtime/pull/673 Related-To: NEO-3599 Signed-off-by: Sylvain Munaut <tnt@246tNt.com> Signed-off-by: Mateusz Jablonski <mateusz.jablonski@intel.com>
127 lines
4.3 KiB
C++
127 lines
4.3 KiB
C++
/*
|
|
* Copyright (C) 2023-2024 Intel Corporation
|
|
*
|
|
* SPDX-License-Identifier: MIT
|
|
*
|
|
*/
|
|
|
|
#include "opencl/source/sharings/gl/linux/gl_sharing_linux.h"
|
|
|
|
#include "opencl/source/context/context.inl"
|
|
#include "opencl/source/helpers/gl_helper.h"
|
|
#include "opencl/source/sharings/gl/gl_arb_sync_event.h"
|
|
|
|
namespace NEO {
|
|
GLSharingFunctionsLinux::GLSharingFunctionsLinux(GLType glhdcType, GLContext glhglrcHandle, GLContext glhglrcHandleBkpCtx, GLDisplay glhdcHandle)
|
|
: glHDCType(glhdcType), glHGLRCHandle(glhglrcHandle), glHGLRCHandleBkpCtx(glhglrcHandleBkpCtx), glHDCHandle(glhdcHandle) {
|
|
GLSharingFunctionsLinux::initGLFunctions();
|
|
}
|
|
GLSharingFunctionsLinux::~GLSharingFunctionsLinux() = default;
|
|
|
|
bool GLSharingFunctionsLinux::isOpenGlExtensionSupported(const unsigned char *pExtensionString) {
|
|
if (glGetStringi == nullptr || glGetIntegerv == nullptr) {
|
|
return false;
|
|
}
|
|
|
|
cl_int numberOfExtensions = 0;
|
|
glGetIntegerv(GL_NUM_EXTENSIONS, &numberOfExtensions);
|
|
for (cl_int i = 0; i < numberOfExtensions; i++) {
|
|
std::basic_string<unsigned char> pString = glGetStringi(GL_EXTENSIONS, i);
|
|
if (pString == pExtensionString) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool GLSharingFunctionsLinux::isOpenGlSharingSupported() {
|
|
|
|
std::basic_string<unsigned char> vendor = glGetString(GL_VENDOR);
|
|
const unsigned char intelVendor[] = "Intel";
|
|
|
|
if ((vendor.empty()) || (vendor != intelVendor)) {
|
|
return false;
|
|
}
|
|
std::basic_string<unsigned char> version = glGetString(GL_VERSION);
|
|
if (version.empty()) {
|
|
return false;
|
|
}
|
|
|
|
bool isOpenGLES = false;
|
|
const unsigned char versionES[] = "OpenGL ES";
|
|
if (version.find(versionES) != std::string::npos) {
|
|
isOpenGLES = true;
|
|
}
|
|
|
|
if (isOpenGLES == true) {
|
|
const unsigned char versionES1[] = "OpenGL ES 1.";
|
|
if (version.find(versionES1) != std::string::npos) {
|
|
const unsigned char supportGLOES[] = "GL_OES_framebuffer_object";
|
|
if (isOpenGlExtensionSupported(supportGLOES) == false) {
|
|
return false;
|
|
}
|
|
}
|
|
} else {
|
|
if (version[0] < '3') {
|
|
const unsigned char supportGLEXT[] = "GL_EXT_framebuffer_object";
|
|
if (isOpenGlExtensionSupported(supportGLEXT) == false) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
GlArbSyncEvent *GLSharingFunctionsLinux::getGlArbSyncEvent(Event &baseEvent) {
|
|
std::lock_guard<std::mutex> lock{glArbEventMutex};
|
|
auto it = glArbEventMapping.find(&baseEvent);
|
|
if (it != glArbEventMapping.end()) {
|
|
return it->second;
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
void GLSharingFunctionsLinux::removeGlArbSyncEventMapping(Event &baseEvent) {
|
|
std::lock_guard<std::mutex> lock{glArbEventMutex};
|
|
auto it = glArbEventMapping.find(&baseEvent);
|
|
if (it == glArbEventMapping.end()) {
|
|
DEBUG_BREAK_IF(it == glArbEventMapping.end());
|
|
return;
|
|
}
|
|
glArbEventMapping.erase(it);
|
|
}
|
|
|
|
GLboolean GLSharingFunctionsLinux::initGLFunctions() {
|
|
std::unique_ptr<OsLibrary> dynLibrary(OsLibrary::load(""));
|
|
|
|
GlFunctionHelper glXGetProc(dynLibrary.get(), "glXGetProcAddress");
|
|
if (glXGetProc.ready()) {
|
|
glXGLInteropQueryDeviceInfo = glXGetProc["glXGLInteropQueryDeviceInfoMESA"];
|
|
glXGLInteropExportObject = glXGetProc["glXGLInteropExportObjectMESA"];
|
|
glXGLInteropFlushObjects = glXGetProc["glXGLInteropFlushObjectsMESA"];
|
|
}
|
|
|
|
GlFunctionHelper eglGetProc(dynLibrary.get(), "eglGetProcAddress");
|
|
if (eglGetProc.ready()) {
|
|
eglGLInteropQueryDeviceInfo = eglGetProc["eglGLInteropQueryDeviceInfoMESA"];
|
|
eglGLInteropExportObject = eglGetProc["eglGLInteropExportObjectMESA"];
|
|
eglGLInteropFlushObjects = eglGetProc["eglGLInteropFlushObjectsMESA"];
|
|
}
|
|
|
|
glGetString = (*dynLibrary)["glGetString"];
|
|
glGetStringi = (*dynLibrary)["glGetStringi"];
|
|
glGetIntegerv = (*dynLibrary)["glGetIntegerv"];
|
|
|
|
this->pfnGlArbSyncObjectCleanup = cleanupArbSyncObject;
|
|
this->pfnGlArbSyncObjectSetup = setupArbSyncObject;
|
|
this->pfnGlArbSyncObjectSignal = signalArbSyncObject;
|
|
this->pfnGlArbSyncObjectWaitServer = serverWaitForArbSyncObject;
|
|
|
|
return 1;
|
|
}
|
|
|
|
template GLSharingFunctionsLinux *Context::getSharing<GLSharingFunctionsLinux>();
|
|
|
|
} // namespace NEO
|